Update to layer 145: Introduce Emoji Statuses (#2062)
This commit is contained in:
parent
e433149da7
commit
e01a878bba
@ -33,6 +33,7 @@ interface GramJsAppConfig extends LimitsConfig {
|
||||
premium_bot_username: string;
|
||||
premium_invoice_slug: string;
|
||||
premium_promo_order: string[];
|
||||
default_emoji_statuses_stickerset_id: string;
|
||||
}
|
||||
|
||||
function buildEmojiSounds(appConfig: GramJsAppConfig) {
|
||||
@ -64,8 +65,8 @@ export function buildAppConfig(json: GramJs.TypeJSONValue): ApiAppConfig {
|
||||
const appConfig = buildJson(json) as GramJsAppConfig;
|
||||
|
||||
return {
|
||||
emojiSounds: buildEmojiSounds(appConfig),
|
||||
defaultReaction: appConfig.reactions_default,
|
||||
emojiSounds: buildEmojiSounds(appConfig),
|
||||
seenByMaxChatMembers: appConfig.chat_read_mark_size_threshold,
|
||||
seenByExpiresAt: appConfig.chat_read_mark_expire_period,
|
||||
autologinDomains: appConfig.autologin_domains || [],
|
||||
@ -75,6 +76,7 @@ export function buildAppConfig(json: GramJs.TypeJSONValue): ApiAppConfig {
|
||||
premiumInvoiceSlug: appConfig.premium_invoice_slug,
|
||||
premiumPromoOrder: appConfig.premium_promo_order,
|
||||
isPremiumPurchaseBlocked: appConfig.premium_purchase_blocked,
|
||||
defaultEmojiStatusesStickerSetId: appConfig.default_emoji_statuses_stickerset_id,
|
||||
limits: {
|
||||
uploadMaxFileparts: getLimit(appConfig, 'upload_max_fileparts', 'uploadMaxFileparts'),
|
||||
stickersFaved: getLimit(appConfig, 'stickers_faved_limit', 'stickersFaved'),
|
||||
|
||||
@ -18,6 +18,7 @@ import {
|
||||
} from './peers';
|
||||
import { omitVirtualClassFields } from './helpers';
|
||||
import { getServerTime } from '../../../util/serverTime';
|
||||
import { buildApiReaction } from './messages';
|
||||
|
||||
type PeerEntityApiChatFields = Omit<ApiChat, (
|
||||
'id' | 'type' | 'title' |
|
||||
@ -453,3 +454,16 @@ export function buildApiChatSettings({
|
||||
canBlockContact: Boolean(blockContact),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildApiChatReactions(availableReactions?: GramJs.TypeChatReactions): string[] | undefined {
|
||||
if (availableReactions instanceof GramJs.ChatReactionsAll) {
|
||||
// TODO Hack before custom reactions are implemented
|
||||
// eslint-disable-next-line max-len
|
||||
return ['👍', '👎', '❤', '🔥', '🥰', '👏', '😁', '🤔', '🤯', '😱', '🤬', '😢', '🎉', '🤩', '🤮', '💩', '🙏', '👌', '🕊', '🤡', '🥱', '🥴', '😍', '🐳', '❤🔥', '🌚', '🌭', '💯', '🤣', '⚡', '🍌', '🏆', '💔', '🤨', '😐', '🍓', '🍾', '💋', '🖕', '😈'];
|
||||
}
|
||||
if (availableReactions instanceof GramJs.ChatReactionsSome) {
|
||||
return availableReactions.reactions.map(buildApiReaction).filter(Boolean);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@ -213,34 +213,50 @@ export function buildMessageReactions(reactions: GramJs.MessageReactions): ApiRe
|
||||
|
||||
return {
|
||||
canSeeList,
|
||||
results: results.map(buildReactionCount),
|
||||
recentReactions: recentReactions?.map(buildMessagePeerReaction),
|
||||
results: results.map(buildReactionCount).filter(Boolean),
|
||||
recentReactions: recentReactions?.map(buildMessagePeerReaction).filter(Boolean),
|
||||
};
|
||||
}
|
||||
|
||||
function buildReactionCount(reactionCount: GramJs.ReactionCount): ApiReactionCount {
|
||||
const { chosen, count, reaction } = reactionCount;
|
||||
function buildReactionCount(reactionCount: GramJs.ReactionCount): ApiReactionCount | undefined {
|
||||
const { chosenOrder, count, reaction } = reactionCount;
|
||||
|
||||
// TODO: Add custom reactions support
|
||||
const apiReaction = buildApiReaction(reaction);
|
||||
if (!apiReaction) return undefined;
|
||||
|
||||
return {
|
||||
isChosen: chosen,
|
||||
isChosen: Boolean(chosenOrder), // TODO: Add custom reactions support
|
||||
count,
|
||||
reaction,
|
||||
reaction: apiReaction,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildMessagePeerReaction(userReaction: GramJs.MessagePeerReaction): ApiUserReaction {
|
||||
export function buildMessagePeerReaction(userReaction: GramJs.MessagePeerReaction): ApiUserReaction | undefined {
|
||||
const {
|
||||
peerId, reaction, big, unread,
|
||||
} = userReaction;
|
||||
|
||||
// TODO: Add custom reactions support
|
||||
const apiReaction = buildApiReaction(reaction);
|
||||
if (!apiReaction) return undefined;
|
||||
|
||||
return {
|
||||
userId: getApiChatIdFromMtpPeer(peerId),
|
||||
reaction,
|
||||
reaction: apiReaction,
|
||||
isUnread: unread,
|
||||
isBig: big,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildApiReaction(reaction: GramJs.TypeReaction): string | undefined {
|
||||
if (reaction instanceof GramJs.ReactionEmoji) {
|
||||
return reaction.emoticon;
|
||||
}
|
||||
// TODO: Add custom reactions support
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function buildApiAvailableReaction(availableReaction: GramJs.AvailableReaction): ApiAvailableReaction {
|
||||
const {
|
||||
selectAnimation, staticIcon, reaction, title,
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import type { Api as GramJs } from '../../../lib/gramjs';
|
||||
|
||||
import type { ApiInvoice, ApiPaymentSavedInfo, ApiPremiumPromo } from '../../types';
|
||||
import type {
|
||||
ApiInvoice, ApiPaymentSavedInfo, ApiPremiumPromo, ApiPremiumSubscriptionOption,
|
||||
} from '../../types';
|
||||
|
||||
import { buildApiDocument, buildApiMessageEntity, buildApiWebDocument } from './messages';
|
||||
import { omitVirtualClassFields } from './helpers';
|
||||
@ -156,15 +158,29 @@ export function buildApiInvoiceFromForm(form: GramJs.payments.PaymentForm): ApiI
|
||||
|
||||
export function buildApiPremiumPromo(promo: GramJs.help.PremiumPromo): ApiPremiumPromo {
|
||||
const {
|
||||
statusText, statusEntities, videos, videoSections, currency, monthlyAmount,
|
||||
statusText, statusEntities, videos, videoSections, periodOptions,
|
||||
} = promo;
|
||||
|
||||
return {
|
||||
statusText,
|
||||
statusEntities: statusEntities.map((l) => buildApiMessageEntity(l)),
|
||||
videoSections,
|
||||
currency,
|
||||
videos: videos.map(buildApiDocument).filter(Boolean),
|
||||
monthlyAmount: monthlyAmount.toString(),
|
||||
options: periodOptions.map(buildApiPremiumSubscriptionOption),
|
||||
};
|
||||
}
|
||||
|
||||
function buildApiPremiumSubscriptionOption(option: GramJs.PremiumSubscriptionOption): ApiPremiumSubscriptionOption {
|
||||
const {
|
||||
current, canPurchaseUpgrade, currency, amount, botUrl, months,
|
||||
} = option;
|
||||
|
||||
return {
|
||||
isCurrent: current,
|
||||
canPurchaseUpgrade,
|
||||
currency,
|
||||
amount: amount.toString(),
|
||||
botUrl,
|
||||
months,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
import type {
|
||||
ApiEmojiStatus,
|
||||
ApiPremiumGiftOption,
|
||||
ApiUser, ApiUserStatus, ApiUserType,
|
||||
} from '../../types';
|
||||
@ -66,6 +67,7 @@ export function buildApiUser(mtpUser: GramJs.TypeUser): ApiUser | undefined {
|
||||
noStatus: !mtpUser.status,
|
||||
...(mtpUser.accessHash && { accessHash: String(mtpUser.accessHash) }),
|
||||
...(avatarHash && { avatarHash }),
|
||||
...(mtpUser.emojiStatus && { emojiStatus: buildApiUserEmojiStatus(mtpUser.emojiStatus) }),
|
||||
hasVideoAvatar,
|
||||
...(mtpUser.bot && mtpUser.botInlinePlaceholder && { botPlaceholder: mtpUser.botInlinePlaceholder }),
|
||||
...(mtpUser.bot && mtpUser.botAttachMenu && { isAttachBot: mtpUser.botAttachMenu }),
|
||||
@ -99,6 +101,18 @@ export function buildApiUserStatus(mtpStatus?: GramJs.TypeUserStatus): ApiUserSt
|
||||
}
|
||||
}
|
||||
|
||||
export function buildApiUserEmojiStatus(mtpEmojiStatus: GramJs.TypeEmojiStatus): ApiEmojiStatus | undefined {
|
||||
if (mtpEmojiStatus instanceof GramJs.EmojiStatus) {
|
||||
return { documentId: mtpEmojiStatus.documentId.toString() };
|
||||
}
|
||||
|
||||
if (mtpEmojiStatus instanceof GramJs.EmojiStatusUntil) {
|
||||
return { documentId: mtpEmojiStatus.documentId.toString(), until: mtpEmojiStatus.until };
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function buildApiUsersAndStatuses(mtpUsers: GramJs.TypeUser[]) {
|
||||
const userStatusesById: Record<string, ApiUserStatus> = {};
|
||||
const users: ApiUser[] = [];
|
||||
|
||||
@ -546,3 +546,16 @@ export function buildInputInvoice(invoice: ApiRequestInputInvoice) {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function buildInputReaction(reaction?: string) {
|
||||
if (!reaction) return new GramJs.ReactionEmpty();
|
||||
return new GramJs.ReactionEmoji({
|
||||
emoticon: reaction,
|
||||
});
|
||||
}
|
||||
|
||||
export function buildInputChatReactions(chatReactions: string[]) {
|
||||
return new GramJs.ChatReactionsSome({
|
||||
reactions: chatReactions.map(buildInputReaction),
|
||||
});
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ import {
|
||||
buildApiChatFolderFromSuggested,
|
||||
buildApiChatBotCommands,
|
||||
buildApiChatSettings,
|
||||
buildApiChatReactions,
|
||||
} from '../apiBuilders/chats';
|
||||
import { buildApiMessage, buildMessageDraft } from '../apiBuilders/messages';
|
||||
import { buildApiUser, buildApiUsersAndStatuses } from '../apiBuilders/users';
|
||||
@ -40,6 +41,7 @@ import {
|
||||
isMessageWithMedia,
|
||||
buildChatBannedRights,
|
||||
buildChatAdminRights,
|
||||
buildInputChatReactions,
|
||||
} from '../gramjsBuilders';
|
||||
import { addEntitiesWithPhotosToLocalDb, addMessageToLocalDb, addPhotoToLocalDb } from '../helpers';
|
||||
import { buildApiPeerId, getApiChatIdFromMtpPeer } from '../apiBuilders/peers';
|
||||
@ -391,7 +393,7 @@ async function getFullChatInfo(chatId: string): Promise<FullChatData | undefined
|
||||
inviteLink: exportedInvite.link,
|
||||
}),
|
||||
groupCallId: call?.id.toString(),
|
||||
enabledReactions: availableReactions,
|
||||
enabledReactions: buildApiChatReactions(availableReactions),
|
||||
requestsPending,
|
||||
recentRequesterIds: recentRequesters?.map((userId) => buildApiPeerId(userId, 'user')),
|
||||
},
|
||||
@ -508,7 +510,7 @@ async function getFullChannelInfo(
|
||||
groupCallId: call ? String(call.id) : undefined,
|
||||
linkedChatId: linkedChatId ? buildApiPeerId(linkedChatId, 'chat') : undefined,
|
||||
botCommands,
|
||||
enabledReactions: availableReactions,
|
||||
enabledReactions: buildApiChatReactions(availableReactions),
|
||||
sendAsId: defaultSendAs ? getApiChatIdFromMtpPeer(defaultSendAs) : undefined,
|
||||
requestsPending,
|
||||
recentRequesterIds: recentRequesters?.map((userId) => buildApiPeerId(userId, 'user')),
|
||||
@ -1259,7 +1261,7 @@ export function setChatEnabledReactions({
|
||||
}) {
|
||||
return invokeRequest(new GramJs.messages.SetChatAvailableReactions({
|
||||
peer: buildInputPeer(chat.id, chat.accessHash),
|
||||
availableReactions: enabledReactions,
|
||||
availableReactions: buildInputChatReactions(enabledReactions),
|
||||
}), true);
|
||||
}
|
||||
|
||||
|
||||
@ -1317,7 +1317,7 @@ export async function fetchSendAs({
|
||||
return {
|
||||
users,
|
||||
chats,
|
||||
ids: result.peers.map(getApiChatIdFromMtpPeer),
|
||||
ids: result.peers.map((sendAsPeer) => getApiChatIdFromMtpPeer(sendAsPeer.peer)),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { ApiChat, ApiUser } from '../../types';
|
||||
import type { ApiChat } from '../../types';
|
||||
import { invokeRequest } from './client';
|
||||
import { Api as GramJs } from '../../../lib/gramjs';
|
||||
import { buildInputPeer } from '../gramjsBuilders';
|
||||
import { buildInputPeer, buildInputReaction } from '../gramjsBuilders';
|
||||
import localDb from '../localDb';
|
||||
import { buildApiAvailableReaction, buildMessagePeerReaction } from '../apiBuilders/messages';
|
||||
import { REACTION_LIST_LIMIT } from '../../../config';
|
||||
@ -79,7 +79,7 @@ export function sendReaction({
|
||||
chat: ApiChat; messageId: number; reaction?: string;
|
||||
}) {
|
||||
return invokeRequest(new GramJs.messages.SendReaction({
|
||||
...(reaction && { reaction }),
|
||||
...(reaction && { reaction: [buildInputReaction(reaction)] }),
|
||||
peer: buildInputPeer(chat.id, chat.accessHash),
|
||||
msgId: messageId,
|
||||
}), true);
|
||||
@ -104,7 +104,7 @@ export async function fetchMessageReactionsList({
|
||||
const result = await invokeRequest(new GramJs.messages.GetMessageReactionsList({
|
||||
peer: buildInputPeer(chat.id, chat.accessHash),
|
||||
id: messageId,
|
||||
...(reaction && { reaction }),
|
||||
...(reaction && { reaction: buildInputReaction(reaction) }),
|
||||
limit: REACTION_LIST_LIMIT,
|
||||
...(offset && { offset }),
|
||||
}));
|
||||
@ -118,9 +118,9 @@ export async function fetchMessageReactionsList({
|
||||
const { nextOffset, reactions, count } = result;
|
||||
|
||||
return {
|
||||
users: result.users.map(buildApiUser).filter<ApiUser>(Boolean as any),
|
||||
users: result.users.map(buildApiUser).filter(Boolean),
|
||||
nextOffset,
|
||||
reactions: reactions.map(buildMessagePeerReaction),
|
||||
reactions: reactions.map(buildMessagePeerReaction).filter(Boolean),
|
||||
count,
|
||||
};
|
||||
}
|
||||
@ -131,6 +131,6 @@ export function setDefaultReaction({
|
||||
reaction: string;
|
||||
}) {
|
||||
return invokeRequest(new GramJs.messages.SetDefaultReaction({
|
||||
reaction,
|
||||
reaction: buildInputReaction(reaction),
|
||||
}));
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ import {
|
||||
buildApiChatFolder,
|
||||
buildApiChatSettings,
|
||||
} from './apiBuilders/chats';
|
||||
import { buildApiUser, buildApiUserStatus } from './apiBuilders/users';
|
||||
import { buildApiUser, buildApiUserEmojiStatus, buildApiUserStatus } from './apiBuilders/users';
|
||||
import {
|
||||
buildMessageFromUpdate,
|
||||
isMessageWithMedia,
|
||||
@ -738,6 +738,14 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
||||
userId: buildApiPeerId(update.userId, 'user'),
|
||||
status: buildApiUserStatus(update.status),
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateUserEmojiStatus) {
|
||||
const emojiStatus = buildApiUserEmojiStatus(update.emojiStatus);
|
||||
if (!emojiStatus) return;
|
||||
onUpdate({
|
||||
'@type': 'updateUserEmojiStatus',
|
||||
userId: buildApiPeerId(update.userId, 'user'),
|
||||
emojiStatus,
|
||||
});
|
||||
} else if (update instanceof GramJs.UpdateUserName) {
|
||||
const apiUserId = buildApiPeerId(update.userId, 'user');
|
||||
const updatedUser = localDb.users[apiUserId];
|
||||
|
||||
@ -160,8 +160,8 @@ export interface ApiCountryCode extends ApiCountry {
|
||||
}
|
||||
|
||||
export interface ApiAppConfig {
|
||||
emojiSounds: Record<string, string>;
|
||||
defaultReaction: string;
|
||||
emojiSounds: Record<string, string>;
|
||||
seenByMaxChatMembers: number;
|
||||
seenByExpiresAt: number;
|
||||
autologinDomains: string[];
|
||||
@ -171,6 +171,7 @@ export interface ApiAppConfig {
|
||||
premiumBotUsername: string;
|
||||
isPremiumPurchaseBlocked: boolean;
|
||||
premiumPromoOrder: string[];
|
||||
defaultEmojiStatusesStickerSetId: string;
|
||||
limits: Record<ApiLimitType, readonly [number, number]>;
|
||||
}
|
||||
|
||||
|
||||
@ -65,10 +65,18 @@ export interface ApiReceipt {
|
||||
}
|
||||
|
||||
export interface ApiPremiumPromo {
|
||||
currency: string;
|
||||
monthlyAmount: string;
|
||||
videoSections: string[];
|
||||
videos: ApiDocument[];
|
||||
statusText: string;
|
||||
statusEntities: ApiMessageEntity[];
|
||||
options: ApiPremiumSubscriptionOption[];
|
||||
}
|
||||
|
||||
export interface ApiPremiumSubscriptionOption {
|
||||
isCurrent?: boolean;
|
||||
canPurchaseUpgrade?: boolean;
|
||||
months: number;
|
||||
currency: string;
|
||||
amount: string;
|
||||
botUrl: string;
|
||||
}
|
||||
|
||||
@ -15,7 +15,9 @@ import type {
|
||||
import type {
|
||||
ApiFormattedText, ApiMessage, ApiPhoto, ApiPoll, ApiReactions, ApiStickerSet, ApiThreadInfo,
|
||||
} from './messages';
|
||||
import type { ApiUser, ApiUserFullInfo, ApiUserStatus } from './users';
|
||||
import type {
|
||||
ApiEmojiStatus, ApiUser, ApiUserFullInfo, ApiUserStatus,
|
||||
} from './users';
|
||||
import type {
|
||||
ApiEmojiInteraction, ApiError, ApiInviteInfo, ApiNotifyException, ApiSessionData,
|
||||
} from './misc';
|
||||
@ -324,6 +326,12 @@ export type ApiUpdateUserStatus = {
|
||||
status: ApiUserStatus;
|
||||
};
|
||||
|
||||
export type ApiUpdateUserEmojiStatus = {
|
||||
'@type': 'updateUserEmojiStatus';
|
||||
userId: string;
|
||||
emojiStatus: ApiEmojiStatus;
|
||||
};
|
||||
|
||||
export type ApiUpdateUserFullInfo = {
|
||||
'@type': 'updateUserFullInfo';
|
||||
id: string;
|
||||
@ -548,7 +556,7 @@ export type ApiUpdate = (
|
||||
ApiUpdateGroupCallConnectionState | ApiUpdateGroupCallLeavePresentation | ApiUpdateGroupCallChatId |
|
||||
ApiUpdatePendingJoinRequests | ApiUpdatePaymentVerificationNeeded | ApiUpdatePaymentStateCompleted |
|
||||
ApiUpdatePhoneCall | ApiUpdatePhoneCallSignalingData | ApiUpdatePhoneCallMediaState |
|
||||
ApiUpdatePhoneCallConnectionState | ApiUpdateBotMenuButton | ApiUpdateTranscribedAudio
|
||||
ApiUpdatePhoneCallConnectionState | ApiUpdateBotMenuButton | ApiUpdateTranscribedAudio | ApiUpdateUserEmojiStatus
|
||||
);
|
||||
|
||||
export type OnApiUpdate = (update: ApiUpdate) => void;
|
||||
|
||||
@ -28,6 +28,7 @@ export interface ApiUser {
|
||||
};
|
||||
fakeType?: ApiFakeType;
|
||||
isAttachBot?: boolean;
|
||||
emojiStatus?: ApiEmojiStatus;
|
||||
|
||||
// Obtained from GetFullUser / UserFullInfo
|
||||
fullInfo?: ApiUserFullInfo;
|
||||
@ -79,3 +80,8 @@ export interface ApiPremiumGiftOption {
|
||||
amount: number;
|
||||
botUrl: string;
|
||||
}
|
||||
|
||||
export interface ApiEmojiStatus {
|
||||
documentId: string;
|
||||
until?: number;
|
||||
}
|
||||
|
||||
@ -8,8 +8,10 @@ import React, {
|
||||
import { fastRaf } from '../../util/schedulers';
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
import buildStyle from '../../util/buildStyle';
|
||||
|
||||
import useHeavyAnimationCheck from '../../hooks/useHeavyAnimationCheck';
|
||||
import useBackgroundMode from '../../hooks/useBackgroundMode';
|
||||
import useOnChange from '../../hooks/useOnChange';
|
||||
|
||||
export type OwnProps = {
|
||||
ref?: RefObject<HTMLDivElement>;
|
||||
@ -28,6 +30,7 @@ export type OwnProps = {
|
||||
onClick?: NoneToVoidFunction;
|
||||
onLoad?: NoneToVoidFunction;
|
||||
onEnded?: NoneToVoidFunction;
|
||||
onLoop?: NoneToVoidFunction;
|
||||
};
|
||||
|
||||
type RLottieClass = typeof import('../../lib/rlottie/RLottie').default;
|
||||
@ -66,6 +69,7 @@ const AnimatedSticker: FC<OwnProps> = ({
|
||||
onClick,
|
||||
onLoad,
|
||||
onEnded,
|
||||
onLoop,
|
||||
}) => {
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
let containerRef = useRef<HTMLDivElement>(null);
|
||||
@ -102,9 +106,10 @@ const AnimatedSticker: FC<OwnProps> = ({
|
||||
quality,
|
||||
isLowPriority,
|
||||
},
|
||||
onLoad,
|
||||
color,
|
||||
onLoad,
|
||||
onEnded,
|
||||
onLoop,
|
||||
);
|
||||
|
||||
if (speed) {
|
||||
@ -125,7 +130,7 @@ const AnimatedSticker: FC<OwnProps> = ({
|
||||
});
|
||||
});
|
||||
}
|
||||
}, [color, animation, tgsUrl, isLowPriority, noLoop, onLoad, quality, size, speed, onEnded]);
|
||||
}, [color, animation, tgsUrl, isLowPriority, noLoop, onLoad, quality, size, speed, onEnded, onLoop]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!animation) return;
|
||||
@ -186,6 +191,12 @@ const AnimatedSticker: FC<OwnProps> = ({
|
||||
fastRaf(unfreezeAnimation);
|
||||
}, [unfreezeAnimation]);
|
||||
|
||||
useOnChange(([prevNoLoop]) => {
|
||||
if (noLoop !== undefined && noLoop !== prevNoLoop) {
|
||||
animation?.setNoLoop(noLoop);
|
||||
}
|
||||
}, [noLoop, animation]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!animation) {
|
||||
return;
|
||||
|
||||
36
src/components/common/CustomEmoji.module.scss
Normal file
36
src/components/common/CustomEmoji.module.scss
Normal file
@ -0,0 +1,36 @@
|
||||
.root {
|
||||
display: inline-block;
|
||||
vertical-align: text-bottom;
|
||||
width: var(--custom-emoji-size);
|
||||
height: var(--custom-emoji-size);
|
||||
|
||||
&.with-grid-fix .media {
|
||||
width: calc(100% + 1px) !important;
|
||||
height: calc(100% + 1px) !important;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
:global(.emoji-small) {
|
||||
vertical-align: baseline !important; // Fix for fallback on Windows, when custom emoji not ready
|
||||
}
|
||||
|
||||
&:global(.custom-color) {
|
||||
--emoji-status-color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.media {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sticker {
|
||||
width: var(--custom-emoji-size) !important;
|
||||
height: var(--custom-emoji-size) !important;
|
||||
display: flex !important;
|
||||
|
||||
:global(canvas) {
|
||||
width: var(--custom-emoji-size) !important;
|
||||
height: var(--custom-emoji-size) !important;
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import React, {
|
||||
memo, useEffect, useMemo, useRef,
|
||||
memo, useCallback, useEffect, useMemo, useRef, useState,
|
||||
} from '../../lib/teact/teact';
|
||||
import { getGlobal } from '../../global';
|
||||
|
||||
import type { FC, TeactNode } from '../../lib/teact/teact';
|
||||
import type { ObserveFn } from '../../hooks/useIntersectionObserver';
|
||||
@ -8,6 +9,10 @@ import type { ObserveFn } from '../../hooks/useIntersectionObserver';
|
||||
import { IS_WEBM_SUPPORTED } from '../../util/environment';
|
||||
import renderText from './helpers/renderText';
|
||||
import safePlay from '../../util/safePlay';
|
||||
import { getPropertyHexColor } from '../../util/themeStyle';
|
||||
import { hexToRgb } from '../../util/switchTheme';
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
import { selectIsAlwaysHighPriorityEmoji, selectIsDefaultEmojiStatusPack } from '../../global/selectors';
|
||||
|
||||
import useMedia from '../../hooks/useMedia';
|
||||
import useEnsureCustomEmoji from '../../hooks/useEnsureCustomEmoji';
|
||||
@ -17,26 +22,56 @@ import useCustomEmoji from './hooks/useCustomEmoji';
|
||||
|
||||
import AnimatedSticker from './AnimatedSticker';
|
||||
|
||||
import styles from './CustomEmoji.module.scss';
|
||||
|
||||
type OwnProps = {
|
||||
documentId: string;
|
||||
children?: TeactNode;
|
||||
className?: string;
|
||||
loopLimit?: number;
|
||||
withGridFix?: boolean;
|
||||
observeIntersection?: ObserveFn;
|
||||
onClick?: NoneToVoidFunction;
|
||||
};
|
||||
|
||||
const STICKER_SIZE = 24;
|
||||
|
||||
const CustomEmojiInner: FC<OwnProps> = ({
|
||||
const CustomEmoji: FC<OwnProps> = ({
|
||||
documentId,
|
||||
children,
|
||||
className,
|
||||
loopLimit,
|
||||
withGridFix,
|
||||
observeIntersection,
|
||||
onClick,
|
||||
}) => {
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
// An alternative to `withGlobal` to avoid adding numerous global containers
|
||||
const customEmoji = useCustomEmoji(documentId);
|
||||
const mediaHash = customEmoji && `sticker${customEmoji.id}`;
|
||||
const isUnsupportedVideo = customEmoji?.isVideo && !IS_WEBM_SUPPORTED;
|
||||
const mediaHash = customEmoji && `sticker${customEmoji.id}${isUnsupportedVideo ? '?size=m' : ''}`;
|
||||
const mediaData = useMedia(mediaHash);
|
||||
const thumbDataUri = useThumbnail(customEmoji);
|
||||
const loopCountRef = useRef(0);
|
||||
const [shouldLoop, setShouldLoop] = useState(true);
|
||||
const [customColor, setCustomColor] = useState<[number, number, number] | undefined>();
|
||||
|
||||
const hasCustomColor = customEmoji && selectIsDefaultEmojiStatusPack(getGlobal(), customEmoji.stickerSetInfo);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasCustomColor || !ref.current) {
|
||||
setCustomColor(undefined);
|
||||
return;
|
||||
}
|
||||
const hexColor = getPropertyHexColor(getComputedStyle(ref.current), '--emoji-status-color');
|
||||
if (!hexColor) {
|
||||
setCustomColor(undefined);
|
||||
return;
|
||||
}
|
||||
const customColorRgb = hexToRgb(hexColor);
|
||||
setCustomColor([customColorRgb.r, customColorRgb.g, customColorRgb.b]);
|
||||
}, [hasCustomColor]);
|
||||
|
||||
const isIntersecting = useIsIntersecting(ref, observeIntersection);
|
||||
|
||||
@ -54,46 +89,99 @@ const CustomEmojiInner: FC<OwnProps> = ({
|
||||
}
|
||||
}, [customEmoji, isIntersecting]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!loopLimit) return undefined;
|
||||
const video = ref.current?.querySelector('video');
|
||||
if (!mediaData || !video) return undefined;
|
||||
|
||||
const returnToStart = () => {
|
||||
loopCountRef.current += 1;
|
||||
if (loopCountRef.current >= loopLimit) {
|
||||
setShouldLoop(false);
|
||||
video.currentTime = 0;
|
||||
} else {
|
||||
video.play();
|
||||
}
|
||||
};
|
||||
|
||||
video.addEventListener('ended', returnToStart);
|
||||
return () => video.removeEventListener('ended', returnToStart);
|
||||
}, [loopLimit, mediaData]);
|
||||
|
||||
const handleStickerLoop = useCallback(() => {
|
||||
if (!loopLimit) return;
|
||||
loopCountRef.current += 1;
|
||||
// Sticker plays 1 more time after disabling loop
|
||||
if (loopCountRef.current >= loopLimit - 1) {
|
||||
setShouldLoop(false);
|
||||
}
|
||||
}, [loopLimit]);
|
||||
|
||||
const content = useMemo(() => {
|
||||
if (!customEmoji || (!thumbDataUri && !mediaData)) {
|
||||
return (children && renderText(children, ['emoji']));
|
||||
}
|
||||
if (!mediaData || (customEmoji.isVideo && !IS_WEBM_SUPPORTED)) {
|
||||
|
||||
if (!mediaData) {
|
||||
return (
|
||||
<img src={thumbDataUri} alt={customEmoji.emoji} />
|
||||
<img className={styles.media} src={thumbDataUri} alt={customEmoji.emoji} />
|
||||
);
|
||||
}
|
||||
if (!customEmoji.isVideo && !customEmoji.isLottie) {
|
||||
|
||||
if (isUnsupportedVideo || (!customEmoji.isVideo && !customEmoji.isLottie)) {
|
||||
return (
|
||||
<img src={mediaData} alt={customEmoji.emoji} />
|
||||
<img className={styles.media} src={mediaData} alt={customEmoji.emoji} />
|
||||
);
|
||||
}
|
||||
|
||||
if (customEmoji.isVideo) {
|
||||
return (
|
||||
<video
|
||||
className={styles.media}
|
||||
playsInline
|
||||
muted
|
||||
loop={!loopLimit}
|
||||
autoPlay={isIntersecting}
|
||||
loop
|
||||
src={mediaData}
|
||||
disablePictureInPicture
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<AnimatedSticker
|
||||
key={mediaData}
|
||||
className={styles.sticker}
|
||||
size={STICKER_SIZE}
|
||||
tgsUrl={mediaData}
|
||||
play={isIntersecting}
|
||||
isLowPriority
|
||||
color={customColor}
|
||||
noLoop={!shouldLoop}
|
||||
isLowPriority={!selectIsAlwaysHighPriorityEmoji(getGlobal(), customEmoji.stickerSetInfo)}
|
||||
onLoop={handleStickerLoop}
|
||||
/>
|
||||
);
|
||||
}, [children, customEmoji, isIntersecting, mediaData, thumbDataUri]);
|
||||
}, [
|
||||
children, customColor, customEmoji, handleStickerLoop, isIntersecting, loopLimit, mediaData, shouldLoop,
|
||||
thumbDataUri,
|
||||
]);
|
||||
|
||||
return (
|
||||
<div ref={ref} className="text-entity-custom-emoji emoji">
|
||||
<div
|
||||
ref={ref}
|
||||
className={buildClassName(
|
||||
styles.root,
|
||||
className,
|
||||
'custom-emoji',
|
||||
'emoji',
|
||||
hasCustomColor && 'custom-color',
|
||||
withGridFix && styles.withGridFix,
|
||||
)}
|
||||
onClick={onClick}
|
||||
>
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(CustomEmojiInner);
|
||||
export default memo(CustomEmoji);
|
||||
|
||||
@ -104,7 +104,7 @@
|
||||
vertical-align: text-bottom !important;
|
||||
}
|
||||
|
||||
.text-entity-custom-emoji {
|
||||
.custom-emoji {
|
||||
// Custom emoji needs to be slightly bigger than normal emoji
|
||||
--custom-emoji-size: calc(1.125 * var(--message-text-size, 1rem) + 1px);
|
||||
margin-inline-end: 1px;
|
||||
|
||||
@ -16,7 +16,11 @@ const FakeIcon: FC<OwnProps> = ({
|
||||
}) => {
|
||||
const lang = useLang();
|
||||
|
||||
return <span className="FakeIcon">{lang(fakeType === 'fake' ? 'FakeMessage' : 'ScamMessage')}</span>;
|
||||
return (
|
||||
<span className="FakeIcon">
|
||||
{lang(fakeType === 'fake' ? 'FakeMessage' : 'ScamMessage')}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(FakeIcon);
|
||||
|
||||
10
src/components/common/FullNameTitle.module.scss
Normal file
10
src/components/common/FullNameTitle.module.scss
Normal file
@ -0,0 +1,10 @@
|
||||
.root {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
--custom-emoji-size: 1.25rem;
|
||||
|
||||
> h3 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
76
src/components/common/FullNameTitle.tsx
Normal file
76
src/components/common/FullNameTitle.tsx
Normal file
@ -0,0 +1,76 @@
|
||||
import React, { memo } from '../../lib/teact/teact';
|
||||
|
||||
import type { ApiChat, ApiUser } from '../../api/types';
|
||||
import type { FC } from '../../lib/teact/teact';
|
||||
import type { ObserveFn } from '../../hooks/useIntersectionObserver';
|
||||
|
||||
import { EMOJI_STATUS_LOOP_LIMIT } from '../../config';
|
||||
import renderText from './helpers/renderText';
|
||||
import { getChatTitle, getUserFullName, isUserId } from '../../global/helpers';
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
|
||||
import useLang from '../../hooks/useLang';
|
||||
|
||||
import VerifiedIcon from './VerifiedIcon';
|
||||
import FakeIcon from './FakeIcon';
|
||||
import CustomEmoji from './CustomEmoji';
|
||||
import PremiumIcon from './PremiumIcon';
|
||||
|
||||
import styles from './FullNameTitle.module.scss';
|
||||
|
||||
type OwnProps = {
|
||||
peer: ApiChat | ApiUser;
|
||||
className?: string;
|
||||
noVerified?: boolean;
|
||||
noFake?: boolean;
|
||||
withEmojiStatus?: boolean;
|
||||
isSavedMessages?: boolean;
|
||||
noLoopLimit?: boolean;
|
||||
onEmojiStatusClick?: NoneToVoidFunction;
|
||||
observeIntersection?: ObserveFn;
|
||||
};
|
||||
|
||||
const FullNameTitle: FC<OwnProps> = ({
|
||||
className,
|
||||
peer,
|
||||
noVerified,
|
||||
noFake,
|
||||
withEmojiStatus,
|
||||
isSavedMessages,
|
||||
noLoopLimit,
|
||||
onEmojiStatusClick,
|
||||
observeIntersection,
|
||||
}) => {
|
||||
const lang = useLang();
|
||||
const isUser = isUserId(peer.id);
|
||||
const title = isUser ? getUserFullName(peer as ApiUser) : getChatTitle(lang, peer as ApiChat);
|
||||
const emojiStatus = isUser && (peer as ApiUser).emojiStatus;
|
||||
const isPremium = isUser && (peer as ApiUser).isPremium;
|
||||
|
||||
if (isSavedMessages) {
|
||||
return (
|
||||
<div className={buildClassName('title', styles.root, className)}>
|
||||
<h3>{lang('SavedMessages')}</h3>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={buildClassName('title', styles.root, className)}>
|
||||
<h3 dir="auto" className="fullName">{renderText(title)}</h3>
|
||||
{!noVerified && peer.isVerified && <VerifiedIcon />}
|
||||
{!noFake && peer.fakeType && <FakeIcon fakeType={peer.fakeType} />}
|
||||
{withEmojiStatus && emojiStatus && (
|
||||
<CustomEmoji
|
||||
documentId={emojiStatus.documentId}
|
||||
loopLimit={!noLoopLimit ? EMOJI_STATUS_LOOP_LIMIT : undefined}
|
||||
observeIntersection={observeIntersection}
|
||||
onClick={onEmojiStatusClick}
|
||||
/>
|
||||
)}
|
||||
{withEmojiStatus && !emojiStatus && isPremium && <PremiumIcon />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(FullNameTitle);
|
||||
@ -10,19 +10,16 @@ import { MediaViewerOrigin } from '../../types';
|
||||
|
||||
import {
|
||||
getChatTypeString,
|
||||
getChatTitle,
|
||||
isChatSuperGroup,
|
||||
} from '../../global/helpers';
|
||||
import { selectChat, selectChatMessages, selectChatOnlineCount } from '../../global/selectors';
|
||||
import renderText from './helpers/renderText';
|
||||
import type { LangFn } from '../../hooks/useLang';
|
||||
import useLang from '../../hooks/useLang';
|
||||
|
||||
import Avatar from './Avatar';
|
||||
import VerifiedIcon from './VerifiedIcon';
|
||||
import TypingStatus from './TypingStatus';
|
||||
import DotAnimation from './DotAnimation';
|
||||
import FakeIcon from './FakeIcon';
|
||||
import FullNameTitle from './FullNameTitle';
|
||||
|
||||
type OwnProps = {
|
||||
chatId: string;
|
||||
@ -152,11 +149,7 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
|
||||
animationLevel={animationLevel}
|
||||
/>
|
||||
<div className="info">
|
||||
<div className="title">
|
||||
<h3 dir="auto">{renderText(getChatTitle(lang, chat))}</h3>
|
||||
{chat.isVerified && <VerifiedIcon />}
|
||||
{chat.fakeType && <FakeIcon fakeType={chat.fakeType} />}
|
||||
</div>
|
||||
<FullNameTitle peer={chat} />
|
||||
{renderStatusOrTyping()}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -9,16 +9,13 @@ import type { AnimationLevel } from '../../types';
|
||||
import { MediaViewerOrigin } from '../../types';
|
||||
|
||||
import { selectChatMessages, selectUser, selectUserStatus } from '../../global/selectors';
|
||||
import { getUserFullName, getUserStatus, isUserOnline } from '../../global/helpers';
|
||||
import renderText from './helpers/renderText';
|
||||
import { getUserStatus, isUserOnline } from '../../global/helpers';
|
||||
import useLang from '../../hooks/useLang';
|
||||
|
||||
import Avatar from './Avatar';
|
||||
import VerifiedIcon from './VerifiedIcon';
|
||||
import TypingStatus from './TypingStatus';
|
||||
import DotAnimation from './DotAnimation';
|
||||
import FakeIcon from './FakeIcon';
|
||||
import PremiumIcon from './PremiumIcon';
|
||||
import FullNameTitle from './FullNameTitle';
|
||||
|
||||
type OwnProps = {
|
||||
userId: string;
|
||||
@ -74,7 +71,6 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
|
||||
} = getActions();
|
||||
|
||||
const { id: userId } = user || {};
|
||||
const fullName = getUserFullName(user);
|
||||
|
||||
useEffect(() => {
|
||||
if (userId && lastSyncTime) {
|
||||
@ -143,18 +139,7 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
|
||||
animationLevel={animationLevel}
|
||||
/>
|
||||
<div className="info">
|
||||
{isSavedMessages ? (
|
||||
<div className="title">
|
||||
<h3>{lang('SavedMessages')}</h3>
|
||||
</div>
|
||||
) : (
|
||||
<div className="title">
|
||||
<h3 dir="auto">{fullName && renderText(fullName)}</h3>
|
||||
{user?.isVerified && <VerifiedIcon />}
|
||||
{user.isPremium && <PremiumIcon />}
|
||||
{user.fakeType && <FakeIcon fakeType={user.fakeType} />}
|
||||
</div>
|
||||
)}
|
||||
<FullNameTitle peer={user} withEmojiStatus isSavedMessages={isSavedMessages} />
|
||||
{(status || (!isSavedMessages && !noStatusOrTyping)) && renderStatusOrTyping()}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -119,9 +119,6 @@
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.fullName {
|
||||
font-weight: 500;
|
||||
font-size: 1.25rem;
|
||||
@ -132,18 +129,28 @@
|
||||
}
|
||||
|
||||
.VerifiedIcon, .PremiumIcon {
|
||||
margin-left: 0.25rem;
|
||||
z-index: 2;
|
||||
--color-fill: var(--color-white);
|
||||
--color-checkmark: var(--color-primary);
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.emoji {
|
||||
.emoji:not(.custom-emoji) {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
background-size: 1.5rem;
|
||||
}
|
||||
|
||||
.custom-emoji {
|
||||
pointer-events: auto;
|
||||
cursor: pointer;
|
||||
|
||||
--custom-emoji-size: 1.5rem;
|
||||
|
||||
&.custom-color {
|
||||
--emoji-status-color: var(--color-white);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.status {
|
||||
|
||||
@ -13,20 +13,18 @@ import { IS_TOUCH_ENV } from '../../util/environment';
|
||||
import { MEMO_EMPTY_ARRAY } from '../../util/memo';
|
||||
import { selectChat, selectUser, selectUserStatus } from '../../global/selectors';
|
||||
import {
|
||||
getUserFullName, getUserStatus, isChatChannel, isUserOnline,
|
||||
getUserStatus, isChatChannel, isUserOnline,
|
||||
} from '../../global/helpers';
|
||||
import renderText from './helpers/renderText';
|
||||
import { captureEvents, SwipeDirection } from '../../util/captureEvents';
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
|
||||
import usePhotosPreload from './hooks/usePhotosPreload';
|
||||
import useLang from '../../hooks/useLang';
|
||||
import usePrevious from '../../hooks/usePrevious';
|
||||
|
||||
import VerifiedIcon from './VerifiedIcon';
|
||||
import FullNameTitle from './FullNameTitle';
|
||||
import ProfilePhoto from './ProfilePhoto';
|
||||
import Transition from '../ui/Transition';
|
||||
import FakeIcon from './FakeIcon';
|
||||
import PremiumIcon from './PremiumIcon';
|
||||
|
||||
import './ProfileInfo.scss';
|
||||
|
||||
@ -70,7 +68,6 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
||||
|
||||
const { id: userId } = user || {};
|
||||
const { id: chatId } = chat || {};
|
||||
const fullName = user ? getUserFullName(user) : (chat ? chat.title : '');
|
||||
const photos = user?.photos || chat?.photos || MEMO_EMPTY_ARRAY;
|
||||
const prevMediaId = usePrevious(mediaId);
|
||||
const prevAvatarOwnerId = usePrevious(avatarOwnerId);
|
||||
@ -196,7 +193,7 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
||||
function renderStatus() {
|
||||
if (user) {
|
||||
return (
|
||||
<div className={`status ${isUserOnline(user, userStatus) ? 'online' : ''}`}>
|
||||
<div className={buildClassName('status', isUserOnline(user, userStatus) && 'online')}>
|
||||
<span className="user-status" dir="auto">{getUserStatus(lang, user, userStatus, serverTimeOffset)}</span>
|
||||
</div>
|
||||
);
|
||||
@ -212,10 +209,6 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
||||
);
|
||||
}
|
||||
|
||||
const isVerifiedIconShown = (user || chat)?.isVerified;
|
||||
const isPremiumIconShown = user?.isPremium;
|
||||
const fakeType = (user || chat)?.fakeType;
|
||||
|
||||
return (
|
||||
<div className={buildClassName('ProfileInfo', forceShowSelf && 'self')} dir={lang.isRtl ? 'rtl' : undefined}>
|
||||
<div className="photo-wrapper">
|
||||
@ -243,17 +236,14 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
||||
</div>
|
||||
|
||||
<div className="info" dir={lang.isRtl ? 'rtl' : 'auto'}>
|
||||
{isSavedMessages ? (
|
||||
<div className="title">
|
||||
<div className="fullName" dir="auto">{lang('SavedMessages')}</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="title">
|
||||
<div className="fullName" dir="auto">{fullName && renderText(fullName)}</div>
|
||||
{isVerifiedIconShown && <VerifiedIcon />}
|
||||
{isPremiumIconShown && <PremiumIcon onClick={handleClickPremium} />}
|
||||
{fakeType && <FakeIcon fakeType={fakeType} />}
|
||||
</div>
|
||||
{(user || chat) && (
|
||||
<FullNameTitle
|
||||
peer={(user || chat)!}
|
||||
withEmojiStatus
|
||||
isSavedMessages={isSavedMessages}
|
||||
onEmojiStatusClick={handleClickPremium}
|
||||
noLoopLimit
|
||||
/>
|
||||
)}
|
||||
{!isSavedMessages && renderStatus()}
|
||||
</div>
|
||||
|
||||
@ -309,7 +309,7 @@ function processEntity(
|
||||
|
||||
if (entity.type === ApiMessageEntityTypes.CustomEmoji) {
|
||||
return (
|
||||
<CustomEmoji documentId={entity.documentId} observeIntersection={observeIntersection}>
|
||||
<CustomEmoji documentId={entity.documentId} observeIntersection={observeIntersection} withGridFix>
|
||||
{renderNestedMessagePart()}
|
||||
</CustomEmoji>
|
||||
);
|
||||
@ -419,7 +419,7 @@ function processEntity(
|
||||
return <Spoiler messageId={messageId}>{renderNestedMessagePart()}</Spoiler>;
|
||||
case ApiMessageEntityTypes.CustomEmoji:
|
||||
return (
|
||||
<CustomEmoji documentId={entity.documentId} observeIntersection={observeIntersection}>
|
||||
<CustomEmoji documentId={entity.documentId} observeIntersection={observeIntersection} withGridFix>
|
||||
{renderNestedMessagePart()}
|
||||
</CustomEmoji>
|
||||
);
|
||||
|
||||
@ -48,6 +48,10 @@
|
||||
&.selected:hover {
|
||||
--background-color: var(--color-chat-active) !important;
|
||||
|
||||
.custom-emoji.custom-color {
|
||||
--emoji-status-color: var(--color-white);
|
||||
}
|
||||
|
||||
.VerifiedIcon, .PremiumIcon {
|
||||
--color-fill: #fff;
|
||||
--color-checkmark: var(--color-primary)
|
||||
@ -95,15 +99,10 @@
|
||||
margin-top: -0.125rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
width: auto;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.icon-muted {
|
||||
font-size: 1.25rem;
|
||||
margin-left: 0.25rem;
|
||||
margin-top: -0.0625rem;
|
||||
margin-left: 0.25rem;
|
||||
color: #c6c8ca;
|
||||
|
||||
body.is-ios & {
|
||||
@ -113,8 +112,6 @@
|
||||
}
|
||||
|
||||
.LastMessageMeta {
|
||||
margin-left: auto;
|
||||
|
||||
body.is-ios & {
|
||||
font-size: 0.875rem;
|
||||
margin-right: 0;
|
||||
@ -177,7 +174,7 @@
|
||||
vertical-align: -0.125rem;
|
||||
}
|
||||
|
||||
.text-entity-custom-emoji {
|
||||
.custom-emoji {
|
||||
--custom-emoji-size: 1.25rem;
|
||||
}
|
||||
|
||||
|
||||
@ -15,7 +15,6 @@ import { MAIN_THREAD_ID } from '../../../api/types';
|
||||
import { ANIMATION_END_DELAY } from '../../../config';
|
||||
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||
import {
|
||||
getChatTitle,
|
||||
isUserId,
|
||||
isActionMessage,
|
||||
getPrivateChatUserId,
|
||||
@ -31,7 +30,7 @@ import {
|
||||
} from '../../../global/helpers';
|
||||
import {
|
||||
selectChat, selectUser, selectChatMessage, selectOutgoingStatus, selectDraft, selectCurrentMessageList,
|
||||
selectNotifySettings, selectNotifyExceptions, selectUserStatus,
|
||||
selectNotifySettings, selectNotifyExceptions, selectUserStatus, selectIsDefaultEmojiStatusPack,
|
||||
} from '../../../global/selectors';
|
||||
import { renderActionMessageText } from '../../common/helpers/renderActionMessageText';
|
||||
import renderText from '../../common/helpers/renderText';
|
||||
@ -47,7 +46,6 @@ import { ChatAnimationTypes } from './hooks';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
|
||||
import Avatar from '../../common/Avatar';
|
||||
import VerifiedIcon from '../../common/VerifiedIcon';
|
||||
import TypingStatus from '../../common/TypingStatus';
|
||||
import LastMessageMeta from '../../common/LastMessageMeta';
|
||||
import DeleteChatModal from '../../common/DeleteChatModal';
|
||||
@ -56,8 +54,7 @@ import Badge from './Badge';
|
||||
import ChatFolderModal from '../ChatFolderModal.async';
|
||||
import ChatCallStatus from './ChatCallStatus';
|
||||
import ReportModal from '../../common/ReportModal';
|
||||
import FakeIcon from '../../common/FakeIcon';
|
||||
import PremiumIcon from '../../common/PremiumIcon';
|
||||
import FullNameTitle from '../../common/FullNameTitle';
|
||||
|
||||
import './Chat.scss';
|
||||
|
||||
@ -77,6 +74,7 @@ type StateProps = {
|
||||
isMuted?: boolean;
|
||||
user?: ApiUser;
|
||||
userStatus?: ApiUserStatus;
|
||||
isEmojiStatusColored?: boolean;
|
||||
actionTargetUserIds?: string[];
|
||||
actionTargetMessage?: ApiMessage;
|
||||
actionTargetChatId?: string;
|
||||
@ -104,6 +102,7 @@ const Chat: FC<OwnProps & StateProps> = ({
|
||||
isMuted,
|
||||
user,
|
||||
userStatus,
|
||||
isEmojiStatusColored,
|
||||
actionTargetUserIds,
|
||||
lastMessageSender,
|
||||
lastMessageOutgoingStatus,
|
||||
@ -325,12 +324,16 @@ const Chat: FC<OwnProps & StateProps> = ({
|
||||
)}
|
||||
</div>
|
||||
<div className="info">
|
||||
<div className="title">
|
||||
<h3>{renderText(getChatTitle(lang, chat, user))}</h3>
|
||||
{chat.isVerified && <VerifiedIcon />}
|
||||
{user?.isPremium && !user.isSelf && <PremiumIcon />}
|
||||
{chat.fakeType && <FakeIcon fakeType={chat.fakeType} />}
|
||||
<div className="info-row">
|
||||
<FullNameTitle
|
||||
peer={user || chat}
|
||||
withEmojiStatus
|
||||
isSavedMessages={chatId === user?.id && user?.isSelf}
|
||||
observeIntersection={observeIntersection}
|
||||
key={!IS_SINGLE_COLUMN_LAYOUT && isEmojiStatusColored ? `${isSelected}` : undefined}
|
||||
/>
|
||||
{isMuted && <i className="icon-muted" />}
|
||||
<div className="separator" />
|
||||
{chat.lastMessage && (
|
||||
<LastMessageMeta
|
||||
message={chat.lastMessage}
|
||||
@ -410,6 +413,11 @@ export default memo(withGlobal<OwnProps>(
|
||||
} = selectCurrentMessageList(global) || {};
|
||||
const isSelected = chatId === currentChatId && currentThreadId === MAIN_THREAD_ID;
|
||||
|
||||
const user = privateChatUserId ? selectUser(global, privateChatUserId) : undefined;
|
||||
const userStatus = privateChatUserId ? selectUserStatus(global, privateChatUserId) : undefined;
|
||||
const statusEmoji = user?.emojiStatus && global.customEmojis.byId[user.emojiStatus.documentId];
|
||||
const isEmojiStatusColored = statusEmoji && selectIsDefaultEmojiStatusPack(global, statusEmoji.stickerSetInfo);
|
||||
|
||||
return {
|
||||
chat,
|
||||
isMuted: selectIsChatMuted(chat, selectNotifySettings(global), selectNotifyExceptions(global)),
|
||||
@ -426,10 +434,9 @@ export default memo(withGlobal<OwnProps>(
|
||||
...(isOutgoing && chat.lastMessage && {
|
||||
lastMessageOutgoingStatus: selectOutgoingStatus(global, chat.lastMessage),
|
||||
}),
|
||||
...(privateChatUserId && {
|
||||
user: selectUser(global, privateChatUserId),
|
||||
userStatus: selectUserStatus(global, privateChatUserId),
|
||||
}),
|
||||
user,
|
||||
userStatus,
|
||||
isEmojiStatusColored,
|
||||
};
|
||||
},
|
||||
)(Chat));
|
||||
|
||||
@ -9,7 +9,6 @@ import type { AnimationLevel } from '../../../types';
|
||||
|
||||
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
|
||||
import {
|
||||
getChatTitle,
|
||||
getPrivateChatUserId,
|
||||
getMessageMediaHash,
|
||||
getMessageMediaThumbDataUri,
|
||||
@ -19,7 +18,6 @@ import {
|
||||
} from '../../../global/helpers';
|
||||
import { selectChat, selectUser } from '../../../global/selectors';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
import renderText from '../../common/helpers/renderText';
|
||||
import { formatPastTimeShort } from '../../../util/dateFormat';
|
||||
import { renderMessageSummary } from '../../common/helpers/renderMessageText';
|
||||
|
||||
@ -29,11 +27,9 @@ import useLang from '../../../hooks/useLang';
|
||||
import useSelectWithEnter from '../../../hooks/useSelectWithEnter';
|
||||
|
||||
import Avatar from '../../common/Avatar';
|
||||
import VerifiedIcon from '../../common/VerifiedIcon';
|
||||
import ListItem from '../../ui/ListItem';
|
||||
import Link from '../../ui/Link';
|
||||
import FakeIcon from '../../common/FakeIcon';
|
||||
import PremiumIcon from '../../common/PremiumIcon';
|
||||
import FullNameTitle from '../../common/FullNameTitle';
|
||||
|
||||
import './ChatMessage.scss';
|
||||
|
||||
@ -95,12 +91,11 @@ const ChatMessage: FC<OwnProps & StateProps> = ({
|
||||
/>
|
||||
<div className="info">
|
||||
<div className="info-row">
|
||||
<div className="title">
|
||||
<h3 dir="auto">{renderText(getChatTitle(lang, chat, privateChatUser))}</h3>
|
||||
{chat.isVerified && <VerifiedIcon />}
|
||||
{privateChatUser?.isPremium && <PremiumIcon />}
|
||||
{chat.fakeType && <FakeIcon fakeType={chat.fakeType} />}
|
||||
</div>
|
||||
<FullNameTitle
|
||||
peer={privateChatUser || chat}
|
||||
withEmojiStatus
|
||||
isSavedMessages={chatId === privateChatUser?.id && privateChatUser?.isSelf}
|
||||
/>
|
||||
<div className="message-date">
|
||||
<Link className="date">
|
||||
{formatPastTimeShort(lang, message.date * 1000)}
|
||||
|
||||
@ -17,12 +17,10 @@
|
||||
}
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
margin-bottom: 0.25rem;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.note,
|
||||
.date {
|
||||
.note {
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 0.875rem;
|
||||
text-align: center;
|
||||
|
||||
@ -5,7 +5,6 @@ import type { FC } from '../../../lib/teact/teact';
|
||||
import type { ApiUser, ApiWebSession } from '../../../api/types';
|
||||
import type { AnimationLevel } from '../../../types';
|
||||
|
||||
import { getUserFullName } from '../../../global/helpers';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
|
||||
import useLang from '../../../hooks/useLang';
|
||||
@ -14,6 +13,7 @@ import useCurrentOrPrev from '../../../hooks/useCurrentOrPrev';
|
||||
import Modal from '../../ui/Modal';
|
||||
import Button from '../../ui/Button';
|
||||
import Avatar from '../../common/Avatar';
|
||||
import FullNameTitle from '../../common/FullNameTitle';
|
||||
|
||||
import styles from './SettingsActiveWebsite.module.scss';
|
||||
|
||||
@ -77,8 +77,8 @@ const SettingsActiveWebsite: FC<OwnProps & StateProps> = ({
|
||||
className={styles.root}
|
||||
>
|
||||
<Avatar className={styles.avatar} user={renderingBot} size="large" animationLevel={animationLevel} withVideo />
|
||||
<h3 className={styles.title} dir="auto">{getUserFullName(renderingBot)}</h3>
|
||||
<div className={styles.date} aria-label={lang('PrivacySettings.LastSeen')}>
|
||||
{renderingBot && <FullNameTitle className={styles.title} peer={renderingBot} />}
|
||||
<div className={styles.note}>
|
||||
{renderingSession?.domain}
|
||||
</div>
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@ import type { ApiWebSession } from '../../../api/types';
|
||||
import type { AnimationLevel } from '../../../types';
|
||||
|
||||
import { formatPastTimeShort } from '../../../util/dateFormat';
|
||||
import { getUserFullName } from '../../../global/helpers';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
|
||||
import useFlag from '../../../hooks/useFlag';
|
||||
@ -19,6 +18,7 @@ import ListItem from '../../ui/ListItem';
|
||||
import ConfirmDialog from '../../ui/ConfirmDialog';
|
||||
import SettingsActiveWebsite from './SettingsActiveWebsite';
|
||||
import Avatar from '../../common/Avatar';
|
||||
import FullNameTitle from '../../common/FullNameTitle';
|
||||
|
||||
import styles from './SettingsActiveWebsites.module.scss';
|
||||
|
||||
@ -116,7 +116,7 @@ const SettingsActiveWebsites: FC<OwnProps & StateProps> = ({
|
||||
<Avatar className={styles.avatar} user={bot} size="tiny" animationLevel={animationLevel} withVideo />
|
||||
<div className="multiline-menu-item full-size" dir="auto">
|
||||
<span className="date">{formatPastTimeShort(lang, session.dateActive * 1000)}</span>
|
||||
<span className="title">{getUserFullName(bot)}</span>
|
||||
{bot && <FullNameTitle className={styles.title} peer={bot} />}
|
||||
<span className={buildClassName('subtitle', 'black', 'tight', styles.platform)}>
|
||||
{session.domain}, {session.browser}, {session.platform}
|
||||
</span>
|
||||
|
||||
@ -7,9 +7,8 @@ import type { ApiChat, ApiCountryCode, ApiUser } from '../../../api/types';
|
||||
import { CHAT_HEIGHT_PX } from '../../../config';
|
||||
import { formatPhoneNumberWithCode } from '../../../util/phoneNumber';
|
||||
import {
|
||||
getChatTitle, getUserFullName, isUserId,
|
||||
isUserId,
|
||||
} from '../../../global/helpers';
|
||||
import renderText from '../../common/helpers/renderText';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useHistoryBack from '../../../hooks/useHistoryBack';
|
||||
@ -20,6 +19,7 @@ import FloatingActionButton from '../../ui/FloatingActionButton';
|
||||
import Avatar from '../../common/Avatar';
|
||||
import Loading from '../../ui/Loading';
|
||||
import BlockUserModal from './BlockUserModal';
|
||||
import FullNameTitle from '../../common/FullNameTitle';
|
||||
|
||||
type OwnProps = {
|
||||
isActive?: boolean;
|
||||
@ -58,6 +58,7 @@ const SettingsPrivacyBlockedUsers: FC<OwnProps & StateProps> = ({
|
||||
const isPrivate = isUserId(contactId);
|
||||
const user = isPrivate ? usersByIds[contactId] : undefined;
|
||||
const chat = !isPrivate ? chatsByIds[contactId] : undefined;
|
||||
const userOrChat = user || chat;
|
||||
|
||||
const className = buildClassName(
|
||||
'Chat chat-item-clickable blocked-list-item small-icon',
|
||||
@ -81,7 +82,7 @@ const SettingsPrivacyBlockedUsers: FC<OwnProps & StateProps> = ({
|
||||
>
|
||||
<Avatar size="medium" user={user} chat={chat} />
|
||||
<div className="contact-info" dir="auto">
|
||||
<h3 dir="auto">{renderText((isPrivate ? getUserFullName(user) : getChatTitle(lang, chat!)) || '')}</h3>
|
||||
{userOrChat && <FullNameTitle peer={userOrChat} />}
|
||||
{user?.phoneNumber && (
|
||||
<div className="contact-phone" dir="auto">{formatPhoneNumberWithCode(phoneCodeList, user.phoneNumber)}</div>
|
||||
)}
|
||||
|
||||
@ -197,6 +197,9 @@ const PremiumFeatureModal: FC<OwnProps> = ({
|
||||
stopScrolling();
|
||||
}, [startScrolling, stopScrolling]);
|
||||
|
||||
// TODO Support all subscription options
|
||||
const month = promo.options.find((option) => option.months === 1)!;
|
||||
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<Button
|
||||
@ -316,7 +319,7 @@ const PremiumFeatureModal: FC<OwnProps> = ({
|
||||
>
|
||||
{isPremium
|
||||
? lang('OK')
|
||||
: lang('SubscribeToPremium', formatCurrency(Number(promo.monthlyAmount), promo.currency, lang.code))}
|
||||
: lang('SubscribeToPremium', formatCurrency(Number(month.amount), month.currency, lang.code))}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -178,6 +178,9 @@ const PremiumMainModal: FC<OwnProps & StateProps> = ({
|
||||
|
||||
if (!promo) return undefined;
|
||||
|
||||
// TODO Support all subscription options
|
||||
const month = promo.options.find((option) => option.months === 1)!;
|
||||
|
||||
function getHeaderText() {
|
||||
if (isGift) {
|
||||
return fromUser?.id === currentUserId
|
||||
@ -284,7 +287,7 @@ const PremiumMainModal: FC<OwnProps & StateProps> = ({
|
||||
<div className={styles.footer}>
|
||||
{/* eslint-disable-next-line react/jsx-no-bind */}
|
||||
<Button className={styles.button} isShiny withPremiumGradient onClick={handleClick}>
|
||||
{lang('SubscribeToPremium', formatCurrency(Number(promo.monthlyAmount), promo.currency, lang.code))}
|
||||
{lang('SubscribeToPremium', formatCurrency(Number(month.amount), month.currency, lang.code))}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -67,13 +67,13 @@
|
||||
max-height: 2.75rem;
|
||||
}
|
||||
|
||||
.emoji:not(.text-entity-custom-emoji) {
|
||||
.emoji:not(.custom-emoji) {
|
||||
width: 0.9375rem;
|
||||
height: 0.9375rem;
|
||||
vertical-align: -2px;
|
||||
}
|
||||
|
||||
.text-entity-custom-emoji {
|
||||
.custom-emoji {
|
||||
--custom-emoji-size: 1.25rem;
|
||||
}
|
||||
|
||||
|
||||
@ -293,9 +293,12 @@
|
||||
}
|
||||
|
||||
.VerifiedIcon, .PremiumIcon {
|
||||
margin-left: 0.25rem;
|
||||
margin-top: 0.0625rem;
|
||||
}
|
||||
|
||||
.custom-emoji {
|
||||
--custom-emoji-size: 1.375rem;
|
||||
}
|
||||
}
|
||||
|
||||
.status,
|
||||
@ -521,7 +524,7 @@
|
||||
font-size: 0.9375rem;
|
||||
}
|
||||
|
||||
.text-entity-custom-emoji {
|
||||
.custom-emoji {
|
||||
--custom-emoji-size: 1.125rem;
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,8 +11,6 @@ import { LoadMoreDirection } from '../../types';
|
||||
import useLang from '../../hooks/useLang';
|
||||
import { selectChatMessage } from '../../global/selectors';
|
||||
import useInfiniteScroll from '../../hooks/useInfiniteScroll';
|
||||
import { getUserFullName } from '../../global/helpers';
|
||||
import renderText from '../common/helpers/renderText';
|
||||
import useFlag from '../../hooks/useFlag';
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
import { formatIntegerCompact } from '../../util/textFormat';
|
||||
@ -25,7 +23,7 @@ import Avatar from '../common/Avatar';
|
||||
import ListItem from '../ui/ListItem';
|
||||
import ReactionStaticEmoji from '../common/ReactionStaticEmoji';
|
||||
import Loading from '../ui/Loading';
|
||||
import PremiumIcon from '../common/PremiumIcon';
|
||||
import FullNameTitle from '../common/FullNameTitle';
|
||||
|
||||
import './ReactorListModal.scss';
|
||||
|
||||
@ -163,7 +161,6 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
|
||||
{viewportIds?.map(
|
||||
(userId) => {
|
||||
const user = usersById[userId];
|
||||
const fullName = getUserFullName(user);
|
||||
const reaction = reactors?.reactions.find((l) => l.userId === userId)?.reaction;
|
||||
return (
|
||||
<ListItem
|
||||
@ -173,10 +170,7 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
|
||||
onClick={() => handleClick(userId)}
|
||||
>
|
||||
<Avatar user={user} size="small" animationLevel={animationLevel} withVideo />
|
||||
<div className="title">
|
||||
<h3 dir="auto">{fullName && renderText(fullName)}</h3>
|
||||
{user.isPremium && <PremiumIcon />}
|
||||
</div>
|
||||
<FullNameTitle peer={user} withEmojiStatus />
|
||||
{reaction && <ReactionStaticEmoji className="reactors-list-emoji" reaction={reaction} />}
|
||||
</ListItem>
|
||||
);
|
||||
|
||||
@ -6,8 +6,7 @@ import React, {
|
||||
import setTooltipItemVisible from '../../../util/setTooltipItemVisible';
|
||||
import { useKeyboardNavigation } from './hooks/useKeyboardNavigation';
|
||||
import { IS_TOUCH_ENV } from '../../../util/environment';
|
||||
import renderText from '../../common/helpers/renderText';
|
||||
import { getUserFullName, isUserId } from '../../../global/helpers';
|
||||
import { isUserId } from '../../../global/helpers';
|
||||
import useMouseInside from '../../../hooks/useMouseInside';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
@ -16,6 +15,7 @@ import { getActions, getGlobal } from '../../../global';
|
||||
import ListItem from '../../ui/ListItem';
|
||||
import Avatar from '../../common/Avatar';
|
||||
import Menu from '../../ui/Menu';
|
||||
import FullNameTitle from '../../common/FullNameTitle';
|
||||
|
||||
import './SendAsMenu.scss';
|
||||
|
||||
@ -93,7 +93,7 @@ const SendAsMenu: FC<OwnProps> = ({
|
||||
{usersById && chatsById && sendAsIds?.map((id, index) => {
|
||||
const user = isUserId(id) ? usersById[id] : undefined;
|
||||
const chat = !user ? chatsById[id] : undefined;
|
||||
const fullName = user ? getUserFullName(user) : chat?.title;
|
||||
const userOrChat = user || chat;
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
@ -110,9 +110,7 @@ const SendAsMenu: FC<OwnProps> = ({
|
||||
className={buildClassName(selectedSendAsId === id && 'selected')}
|
||||
/>
|
||||
<div className="info">
|
||||
<div className="title">
|
||||
<h3 dir="auto">{fullName && renderText(fullName)}</h3>
|
||||
</div>
|
||||
{userOrChat && <FullNameTitle peer={userOrChat} noFake />}
|
||||
<span className="subtitle">{user
|
||||
? lang('VoipGroupPersonalAccount')
|
||||
: lang('Subscribers', chat?.membersCount, 'i')}
|
||||
|
||||
@ -47,8 +47,7 @@
|
||||
}
|
||||
|
||||
> .Avatar,
|
||||
> .message-content-wrapper,
|
||||
> .chat-avatar-premium {
|
||||
> .message-content-wrapper {
|
||||
opacity: 1;
|
||||
transform: scale(1) translateX(0);
|
||||
transition: transform var(--select-transition);
|
||||
@ -71,24 +70,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
& > .chat-avatar-premium {
|
||||
position: absolute;
|
||||
bottom: -0.1875rem;
|
||||
left: 1.25rem;
|
||||
height: 0.75rem;
|
||||
z-index: 1;
|
||||
|
||||
& > svg {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
--color-fill: white;
|
||||
|
||||
@media (max-width: 600px) {
|
||||
left: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.quick-reaction {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
@ -298,8 +279,7 @@
|
||||
|
||||
&:not(.own) {
|
||||
> .Avatar,
|
||||
> .message-content-wrapper,
|
||||
> .chat-avatar-premium {
|
||||
> .message-content-wrapper {
|
||||
transform: translateX(2.5rem);
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ import {
|
||||
} from '../../../types';
|
||||
|
||||
import { IS_ANDROID, IS_TOUCH_ENV } from '../../../util/environment';
|
||||
import { EMOJI_STATUS_LOOP_LIMIT } from '../../../config';
|
||||
import {
|
||||
selectChat,
|
||||
selectChatMessage,
|
||||
@ -118,8 +119,10 @@ import CommentButton from './CommentButton';
|
||||
import Reactions from './Reactions';
|
||||
import ReactionStaticEmoji from '../../common/ReactionStaticEmoji';
|
||||
import MessagePhoneCall from './MessagePhoneCall';
|
||||
import PremiumIcon from '../../common/PremiumIcon';
|
||||
import DotAnimation from '../../common/DotAnimation';
|
||||
import CustomEmoji from '../../common/CustomEmoji';
|
||||
import PremiumIcon from '../../common/PremiumIcon';
|
||||
import FakeIcon from '../../common/FakeIcon';
|
||||
|
||||
import './Message.scss';
|
||||
|
||||
@ -609,23 +612,19 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
const avatarUser = (avatarPeer && isAvatarPeerUser) ? avatarPeer as ApiUser : undefined;
|
||||
const avatarChat = (avatarPeer && !isAvatarPeerUser) ? avatarPeer as ApiChat : undefined;
|
||||
const hiddenName = (!avatarPeer && forwardInfo) ? forwardInfo.hiddenUserName : undefined;
|
||||
const isAvatarPremium = avatarUser?.isPremium;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Avatar
|
||||
size="small"
|
||||
user={avatarUser}
|
||||
chat={avatarChat}
|
||||
text={hiddenName}
|
||||
lastSyncTime={lastSyncTime}
|
||||
onClick={(avatarUser || avatarChat) ? handleAvatarClick : undefined}
|
||||
observeIntersection={observeIntersectionForMedia}
|
||||
animationLevel={animationLevel}
|
||||
withVideo
|
||||
/>
|
||||
{isAvatarPremium && <PremiumIcon className="chat-avatar-premium" />}
|
||||
</>
|
||||
<Avatar
|
||||
size="small"
|
||||
user={avatarUser}
|
||||
chat={avatarChat}
|
||||
text={hiddenName}
|
||||
lastSyncTime={lastSyncTime}
|
||||
onClick={(avatarUser || avatarChat) ? handleAvatarClick : undefined}
|
||||
observeIntersection={observeIntersectionForMedia}
|
||||
animationLevel={animationLevel}
|
||||
withVideo
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -904,16 +903,27 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
} else if (forwardInfo?.hiddenUserName) {
|
||||
senderTitle = forwardInfo.hiddenUserName;
|
||||
}
|
||||
const senderEmojiStatus = senderPeer && 'emojiStatus' in senderPeer && senderPeer.emojiStatus;
|
||||
const senderIsPremium = senderPeer && 'isPremium' in senderPeer && senderPeer.isPremium;
|
||||
|
||||
return (
|
||||
<div className="message-title" dir="ltr">
|
||||
{senderTitle ? (
|
||||
<span
|
||||
className={buildClassName('interactive', senderColor)}
|
||||
className={buildClassName('message-title-name interactive', senderColor)}
|
||||
onClick={handleSenderClick}
|
||||
dir="auto"
|
||||
>
|
||||
{renderText(senderTitle)}
|
||||
{!asForwarded && senderEmojiStatus && (
|
||||
<CustomEmoji
|
||||
documentId={senderEmojiStatus.documentId}
|
||||
loopLimit={EMOJI_STATUS_LOOP_LIMIT}
|
||||
observeIntersection={observeIntersectionForAnimatedStickers}
|
||||
/>
|
||||
)}
|
||||
{!asForwarded && !senderEmojiStatus && senderIsPremium && <PremiumIcon />}
|
||||
{senderPeer?.fakeType && <FakeIcon fakeType={senderPeer.fakeType} />}
|
||||
</span>
|
||||
) : !botSender ? (
|
||||
NBSP
|
||||
|
||||
@ -218,6 +218,10 @@
|
||||
unicode-bidi: plaintext;
|
||||
display: flex;
|
||||
|
||||
.message-title-name {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
& > .interactive {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@ -235,6 +239,14 @@
|
||||
@for $i from 1 through 8 {
|
||||
& > .color-#{$i} {
|
||||
color: var(--color-user-#{$i});
|
||||
|
||||
.custom-emoji.custom-color {
|
||||
--emoji-status-color: var(--color-user-#{$i});
|
||||
}
|
||||
|
||||
.PremiumIcon {
|
||||
--color-fill: var(--color-user-#{$i});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,6 +267,21 @@
|
||||
padding-left: 0.25rem;
|
||||
}
|
||||
|
||||
.custom-emoji {
|
||||
--custom-emoji-size: 1.25rem;
|
||||
margin-left: 0.25rem;
|
||||
|
||||
&.custom-color {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.PremiumIcon {
|
||||
vertical-align: middle;
|
||||
opacity: 0.5;
|
||||
margin-left: 0.25rem;
|
||||
}
|
||||
|
||||
.admin-title {
|
||||
flex: 1;
|
||||
margin-left: 1rem;
|
||||
@ -392,7 +419,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.custom-shape) .emoji {
|
||||
&:not(.custom-shape) .emoji:not(.custom-emoji) {
|
||||
display: inline-block;
|
||||
width: 1.25rem;
|
||||
background-size: 1.25rem;
|
||||
@ -413,7 +440,7 @@
|
||||
background-size: calc(1.25 * var(--message-text-size, 1rem));
|
||||
}
|
||||
|
||||
.text-entity-custom-emoji {
|
||||
.custom-emoji {
|
||||
--custom-emoji-size: calc(1.25 * var(--message-text-size, 1rem));
|
||||
}
|
||||
}
|
||||
@ -833,31 +860,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.text-entity-custom-emoji {
|
||||
display: inline-block;
|
||||
vertical-align: text-bottom;
|
||||
--custom-emoji-size: 1.5rem;
|
||||
width: var(--custom-emoji-size);
|
||||
height: var(--custom-emoji-size);
|
||||
|
||||
& > video, & > img {
|
||||
width: calc(100% + 1px) !important;
|
||||
height: calc(100% + 1px) !important;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
& > .AnimatedSticker {
|
||||
width: var(--custom-emoji-size) !important;
|
||||
height: var(--custom-emoji-size) !important;
|
||||
display: flex !important;
|
||||
|
||||
& > canvas {
|
||||
width: var(--custom-emoji-size) !important;
|
||||
height: var(--custom-emoji-size) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text-entity-code {
|
||||
color: var(--color-code);
|
||||
background: var(--color-code-bg);
|
||||
|
||||
@ -62,10 +62,6 @@
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.VerifiedIcon, .PremiumIcon {
|
||||
margin-left: 0.25rem;
|
||||
}
|
||||
|
||||
.emoji {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
|
||||
@ -13,8 +13,6 @@ import {
|
||||
selectCurrentTextSearch,
|
||||
} from '../../global/selectors';
|
||||
import {
|
||||
getChatTitle,
|
||||
getUserFullName,
|
||||
isChatChannel,
|
||||
} from '../../global/helpers';
|
||||
import useLang from '../../hooks/useLang';
|
||||
@ -22,12 +20,12 @@ import useKeyboardListNavigation from '../../hooks/useKeyboardListNavigation';
|
||||
import useHistoryBack from '../../hooks/useHistoryBack';
|
||||
import useInfiniteScroll from '../../hooks/useInfiniteScroll';
|
||||
import { renderMessageSummary } from '../common/helpers/renderMessageText';
|
||||
import renderText from '../common/helpers/renderText';
|
||||
|
||||
import InfiniteScroll from '../ui/InfiniteScroll';
|
||||
import ListItem from '../ui/ListItem';
|
||||
import LastMessageMeta from '../common/LastMessageMeta';
|
||||
import Avatar from '../common/Avatar';
|
||||
import FullNameTitle from '../common/FullNameTitle';
|
||||
|
||||
import './RightSearch.scss';
|
||||
|
||||
@ -122,7 +120,6 @@ const RightSearch: FC<OwnProps & StateProps> = ({
|
||||
senderChat?: ApiChat;
|
||||
onClick: NoneToVoidFunction;
|
||||
}) => {
|
||||
const title = senderChat ? getChatTitle(lang, senderChat) : getUserFullName(senderUser);
|
||||
const text = renderMessageSummary(lang, message, undefined, query);
|
||||
|
||||
return (
|
||||
@ -134,8 +131,8 @@ const RightSearch: FC<OwnProps & StateProps> = ({
|
||||
>
|
||||
<Avatar chat={senderChat} user={senderUser} animationLevel={animationLevel} withVideo />
|
||||
<div className="info">
|
||||
<div className="title">
|
||||
<h3 dir="auto">{title && renderText(title)}</h3>
|
||||
<div className="search-result-message-top">
|
||||
<FullNameTitle peer={(senderUser || senderChat)!} />
|
||||
<LastMessageMeta message={message} />
|
||||
</div>
|
||||
<div className="subtitle" dir="auto">
|
||||
|
||||
@ -173,6 +173,7 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.info-row,
|
||||
.title,
|
||||
.subtitle {
|
||||
overflow: hidden;
|
||||
@ -181,6 +182,10 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.separator {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
h3,
|
||||
.last-message,
|
||||
.status,
|
||||
@ -199,15 +204,6 @@
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.VerifiedIcon {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.PremiumIcon,
|
||||
.VerifiedIcon {
|
||||
margin-left: 0.25rem;
|
||||
}
|
||||
|
||||
.emoji {
|
||||
vertical-align: text-bottom;
|
||||
background-position: 0 0;
|
||||
@ -289,9 +285,14 @@
|
||||
|
||||
&.search-result-message {
|
||||
.title {
|
||||
flex-grow: 1;
|
||||
padding-right: 0.125rem;
|
||||
}
|
||||
|
||||
.search-result-message-top {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
h3 {
|
||||
max-width: 80%;
|
||||
}
|
||||
@ -307,11 +308,6 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
.LastMessageMeta {
|
||||
margin-left: auto;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: var(--color-text-secondary);
|
||||
|
||||
|
||||
@ -150,6 +150,7 @@ export const STICKER_SIZE_INLINE_BOT_RESULT = 100;
|
||||
export const STICKER_SIZE_JOIN_REQUESTS = 140;
|
||||
export const STICKER_SIZE_INVITES = 140;
|
||||
export const RECENT_STICKERS_LIMIT = 20;
|
||||
export const EMOJI_STATUS_LOOP_LIMIT = 2;
|
||||
export const RECENT_SYMBOL_SET_ID = 'recent';
|
||||
export const FAVORITE_SYMBOL_SET_ID = 'favorite';
|
||||
export const CHAT_STICKER_SET_ID = 'chatStickers';
|
||||
@ -206,6 +207,7 @@ export const API_CHAT_TYPES = ['bots', 'channels', 'chats', 'users'] as const;
|
||||
// MTProto constants
|
||||
export const SERVICE_NOTIFICATIONS_USER_ID = '777000';
|
||||
export const REPLIES_USER_ID = '1271266957'; // TODO For Test connection ID must be equal to 708513
|
||||
export const RESTRICTED_EMOJI_SET_ID = '7173162320003080';
|
||||
export const ALL_FOLDER_ID = 0;
|
||||
export const ARCHIVED_FOLDER_ID = 1;
|
||||
export const DELETED_COMMENTS_CHANNEL_ID = '-777';
|
||||
|
||||
@ -411,13 +411,16 @@ addActionHandler('openGiftPremiumModal', async (global, actions, payload) => {
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
|
||||
// TODO Support all subscription options
|
||||
const month = result.promo.options.find((option) => option.months === 1)!;
|
||||
|
||||
setGlobal({
|
||||
...global,
|
||||
giftPremiumModal: {
|
||||
isOpen: true,
|
||||
forUserId,
|
||||
monthlyCurrency: result.promo.currency,
|
||||
monthlyAmount: result.promo.monthlyAmount,
|
||||
monthlyCurrency: month.currency,
|
||||
monthlyAmount: month.amount,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@ -42,6 +42,10 @@ addActionHandler('apiUpdate', (global, actions, update) => {
|
||||
return updateUser(global, update.id, update.user);
|
||||
}
|
||||
|
||||
case 'updateUserEmojiStatus': {
|
||||
return updateUser(global, update.userId, { emojiStatus: update.emojiStatus });
|
||||
}
|
||||
|
||||
case 'updateUserStatus': {
|
||||
// Status updates come very often so we throttle them
|
||||
scheduleStatusUpdate(update.userId, update.status);
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import type { ApiMessage, ApiReactions } from '../../api/types';
|
||||
import type {
|
||||
ApiMessage, ApiReactions,
|
||||
} from '../../api/types';
|
||||
import type { GlobalState } from '../types';
|
||||
|
||||
export function getMessageRecentReaction(message: Partial<ApiMessage>) {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import type { GlobalState } from '../types';
|
||||
import type { ApiStickerSetInfo, ApiSticker, ApiStickerSet } from '../../api/types';
|
||||
|
||||
import { RESTRICTED_EMOJI_SET_ID } from '../../config';
|
||||
import { selectIsCurrentUserPremium } from './users';
|
||||
|
||||
export function selectIsStickerFavorite(global: GlobalState, sticker: ApiSticker) {
|
||||
@ -117,3 +118,11 @@ export function selectLocalAnimatedEmojiEffect(emoji: string) {
|
||||
export function selectLocalAnimatedEmojiEffectByName(name: string) {
|
||||
return name === 'Cumshot' ? '🍆' : undefined;
|
||||
}
|
||||
|
||||
export function selectIsDefaultEmojiStatusPack(global: GlobalState, pack: ApiStickerSetInfo) {
|
||||
return 'id' in pack && pack.id === global.appConfig?.defaultEmojiStatusesStickerSetId;
|
||||
}
|
||||
|
||||
export function selectIsAlwaysHighPriorityEmoji(global: GlobalState, pack: ApiStickerSetInfo) {
|
||||
return selectIsDefaultEmojiStatusPack(global, pack) || ('id' in pack && pack.id === RESTRICTED_EMOJI_SET_ID);
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const api = require('./api');
|
||||
|
||||
const LAYER = 144;
|
||||
const LAYER = 145;
|
||||
const tlobjects = {};
|
||||
|
||||
for (const tl of Object.values(api)) {
|
||||
|
||||
338
src/lib/gramjs/tl/api.d.ts
vendored
338
src/lib/gramjs/tl/api.d.ts
vendored
File diff suppressed because one or more lines are too long
@ -64,7 +64,7 @@ storage.fileMov#4b09ebbc = storage.FileType;
|
||||
storage.fileMp4#b3cea0e4 = storage.FileType;
|
||||
storage.fileWebp#1081464c = storage.FileType;
|
||||
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 bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?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#5d99adee flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus = User;
|
||||
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
||||
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
|
||||
userStatusEmpty#9d05049 = UserStatus;
|
||||
@ -78,8 +78,8 @@ chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5
|
||||
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 join_to_send:flags.28?true join_request:flags.29?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;
|
||||
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#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;
|
||||
chatFull#c9d31138 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions = ChatFull;
|
||||
channelFull#f2355507 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel: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?ChatReactions = ChatFull;
|
||||
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
|
||||
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
|
||||
chatParticipantAdmin#a0933f5b user_id:long inviter_id:long date:int = ChatParticipant;
|
||||
@ -241,7 +241,7 @@ updateChannelMessageViews#f226ac08 channel_id:long id:int views:int = Update;
|
||||
updateChatParticipantAdmin#d7ca61a2 chat_id:long user_id:long is_admin:Bool version:int = Update;
|
||||
updateNewStickerSet#688a30aa stickerset:messages.StickerSet = Update;
|
||||
updateStickerSetsOrder#bb2d201 flags:# masks:flags.0?true emojis:flags.1?true order:Vector<long> = Update;
|
||||
updateStickerSets#43ae3dec = Update;
|
||||
updateStickerSets#31c24808 flags:# masks:flags.0?true emojis:flags.1?true = Update;
|
||||
updateSavedGifs#9375341e = Update;
|
||||
updateBotInlineQuery#496f379c flags:# query_id:long user_id:long query:string geo:flags.0?GeoPoint peer_type:flags.1?InlineQueryPeerType offset:string = Update;
|
||||
updateBotInlineSend#12f12a07 flags:# user_id:long query:string geo:flags.0?GeoPoint id:string msg_id:flags.1?InputBotInlineMessageID = Update;
|
||||
@ -310,6 +310,10 @@ updateBotMenuButton#14b85813 bot_id:long button:BotMenuButton = Update;
|
||||
updateSavedRingtones#74d8be99 = Update;
|
||||
updateTranscribedAudio#84cd5a flags:# pending:flags.0?true peer:Peer msg_id:int transcription_id:long text:string = Update;
|
||||
updateReadFeaturedEmojiStickers#fb4c496c = Update;
|
||||
updateUserEmojiStatus#28373599 user_id:long emoji_status:EmojiStatus = Update;
|
||||
updateRecentEmojiStatuses#30f443db = Update;
|
||||
updateRecentReactions#6f7863f4 = Update;
|
||||
updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?true stickerset:long = Update;
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference;
|
||||
updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference;
|
||||
@ -328,7 +332,7 @@ photos.photo#20212ca8 photo:Photo users:Vector<User> = photos.Photo;
|
||||
upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
|
||||
upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes encryption_iv:bytes file_hashes:Vector<FileHash> = upload.File;
|
||||
dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true this_port_only:flags.5?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption;
|
||||
config#330b4067 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true pfs_enabled:flags.13?true force_try_ipv6:flags.14?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int pinned_infolder_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int = Config;
|
||||
config#232566ac flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true pfs_enabled:flags.13?true force_try_ipv6:flags.14?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int pinned_infolder_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int reactions_default:flags.15?Reaction = Config;
|
||||
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
|
||||
help.appUpdate#ccbbce30 flags:# can_not_skip:flags.0?true id:int version:string text:string entities:Vector<MessageEntity> document:flags.1?Document url:flags.2?string sticker:flags.3?Document = help.AppUpdate;
|
||||
help.noAppUpdate#c45a6536 = help.AppUpdate;
|
||||
@ -435,7 +439,7 @@ webPage#e89c45b2 flags:# id:long url:string display_url:string hash:int type:fla
|
||||
webPageNotModified#7311ca11 flags:# cached_page_views:flags.0?int = WebPage;
|
||||
authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true encrypted_requests_disabled:flags.3?true call_requests_disabled:flags.4?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
|
||||
account.authorizations#4bff8ea0 authorization_ttl_days:int authorizations:Vector<Authorization> = account.Authorizations;
|
||||
account.password#185b184f flags:# has_recovery:flags.0?true has_secure_values:flags.1?true has_password:flags.2?true current_algo:flags.2?PasswordKdfAlgo srp_B:flags.2?bytes srp_id:flags.2?long hint:flags.3?string email_unconfirmed_pattern:flags.4?string new_algo:PasswordKdfAlgo new_secure_algo:SecurePasswordKdfAlgo secure_random:bytes pending_reset_date:flags.5?int = account.Password;
|
||||
account.password#957b50fb flags:# has_recovery:flags.0?true has_secure_values:flags.1?true has_password:flags.2?true current_algo:flags.2?PasswordKdfAlgo srp_B:flags.2?bytes srp_id:flags.2?long hint:flags.3?string email_unconfirmed_pattern:flags.4?string new_algo:PasswordKdfAlgo new_secure_algo:SecurePasswordKdfAlgo secure_random:bytes pending_reset_date:flags.5?int login_email_pattern:flags.6?string = account.Password;
|
||||
account.passwordSettings#9a5c33e5 flags:# email:flags.0?string secure_settings:flags.1?SecureSecretSettings = account.PasswordSettings;
|
||||
account.passwordInputSettings#c23727c9 flags:# new_algo:flags.0?PasswordKdfAlgo new_password_hash:flags.0?bytes hint:flags.0?string email:flags.1?string new_secure_settings:flags.2?SecureSecretSettings = account.PasswordInputSettings;
|
||||
auth.passwordRecovery#137948a5 email_pattern:string = auth.PasswordRecovery;
|
||||
@ -452,6 +456,8 @@ inputStickerSetAnimatedEmoji#28703c8 = InputStickerSet;
|
||||
inputStickerSetDice#e67f520e emoticon:string = InputStickerSet;
|
||||
inputStickerSetAnimatedEmojiAnimations#cde3739 = InputStickerSet;
|
||||
inputStickerSetPremiumGifts#c88b3b02 = InputStickerSet;
|
||||
inputStickerSetEmojiGenericAnimations#4c4d4ce = InputStickerSet;
|
||||
inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet;
|
||||
stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true emojis:flags.7?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet;
|
||||
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
|
||||
messages.stickerSetNotModified#d3f924eb = messages.StickerSet;
|
||||
@ -559,6 +565,8 @@ auth.sentCodeTypeSms#c000bba2 length:int = auth.SentCodeType;
|
||||
auth.sentCodeTypeCall#5353e5a7 length:int = auth.SentCodeType;
|
||||
auth.sentCodeTypeFlashCall#ab03c6d9 pattern:string = auth.SentCodeType;
|
||||
auth.sentCodeTypeMissedCall#82006484 prefix:string length:int = auth.SentCodeType;
|
||||
auth.sentCodeTypeEmailCode#5a159841 flags:# apple_signin_allowed:flags.0?true google_signin_allowed:flags.1?true email_pattern:string length:int next_phone_login_date:flags.2?int = auth.SentCodeType;
|
||||
auth.sentCodeTypeSetUpEmailRequired#a5491dea flags:# apple_signin_allowed:flags.0?true google_signin_allowed:flags.1?true = auth.SentCodeType;
|
||||
messages.botCallbackAnswer#36585ea4 flags:# alert:flags.1?true has_url:flags.3?true native_ui:flags.4?true message:flags.0?string url:flags.2?string cache_time:int = messages.BotCallbackAnswer;
|
||||
messages.messageEditData#26b5dde6 flags:# caption:flags.0?true = messages.MessageEditData;
|
||||
inputBotInlineMessageID#890c3d89 dc_id:int id:long access_hash:long = InputBotInlineMessageID;
|
||||
@ -659,7 +667,7 @@ webDocumentNoProxy#f9c8bcc6 url:string size:int mime_type:string attributes:Vect
|
||||
inputWebDocument#9bed434d url:string size:int mime_type:string attributes:Vector<DocumentAttribute> = InputWebDocument;
|
||||
inputWebFileLocation#c239d686 url:string access_hash:long = InputWebFileLocation;
|
||||
inputWebFileGeoPointLocation#9f2221c9 geo_point:InputGeoPoint access_hash:long w:int h:int zoom:int scale:int = InputWebFileLocation;
|
||||
inputWebFileAudioAlbumThumbLocation#f46fe924 flags:# document:flags.0?InputDocument title:flags.1?string performer:flags.1?string = InputWebFileLocation;
|
||||
inputWebFileAudioAlbumThumbLocation#f46fe924 flags:# small:flags.2?true document:flags.0?InputDocument title:flags.1?string performer:flags.1?string = InputWebFileLocation;
|
||||
upload.webFile#21e753bc size:int mime_type:string file_type:storage.FileType mtime:int bytes:bytes = upload.WebFile;
|
||||
payments.paymentForm#a0058751 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice provider_id:long url:string native_provider:flags.4?string native_params:flags.4?DataJSON additional_methods:flags.6?Vector<PaymentFormMethod> saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?Vector<PaymentSavedCredentials> users:Vector<User> = payments.PaymentForm;
|
||||
payments.validatedRequestedInfo#d1451883 flags:# id:flags.0?string shipping_options:flags.1?Vector<ShippingOption> = payments.ValidatedRequestedInfo;
|
||||
@ -729,7 +737,7 @@ channelAdminLogEventActionChangeHistoryTTL#6e941a38 prev_value:int new_value:int
|
||||
channelAdminLogEventActionParticipantJoinByRequest#afb6144a invite:ExportedChatInvite approved_by:long = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionToggleNoForwards#cb2ac766 new_value:Bool = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionSendMessage#278f2868 message:Message = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeAvailableReactions#9cf7f76a prev_value:Vector<string> new_value:Vector<string> = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeAvailableReactions#be4e0ef8 prev_value:ChatReactions new_value:ChatReactions = ChannelAdminLogEventAction;
|
||||
channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
|
||||
channels.adminLogResults#ed8af74d events:Vector<ChannelAdminLogEvent> chats:Vector<Chat> users:Vector<User> = channels.AdminLogResults;
|
||||
channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true send:flags.16?true = ChannelAdminLogEventsFilter;
|
||||
@ -961,11 +969,11 @@ searchResultsCalendarPeriod#c9b0539f date:int min_msg_id:int max_msg_id:int coun
|
||||
messages.searchResultsCalendar#147ee23c flags:# inexact:flags.0?true count:int min_date:int min_msg_id:int offset_id_offset:flags.1?int periods:Vector<SearchResultsCalendarPeriod> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.SearchResultsCalendar;
|
||||
searchResultPosition#7f648b67 msg_id:int date:int offset:int = SearchResultsPosition;
|
||||
messages.searchResultsPositions#53b22baf count:int positions:Vector<SearchResultsPosition> = messages.SearchResultsPositions;
|
||||
channels.sendAsPeers#8356cda9 peers:Vector<Peer> chats:Vector<Chat> users:Vector<User> = channels.SendAsPeers;
|
||||
channels.sendAsPeers#f496b0c6 peers:Vector<SendAsPeer> chats:Vector<Chat> users:Vector<User> = channels.SendAsPeers;
|
||||
users.userFull#3b6d152e full_user:UserFull chats:Vector<Chat> users:Vector<User> = users.UserFull;
|
||||
messages.peerSettings#6880b94d settings:PeerSettings chats:Vector<Chat> users:Vector<User> = messages.PeerSettings;
|
||||
auth.loggedOut#c3a2835f flags:# future_auth_token:flags.0?bytes = auth.LoggedOut;
|
||||
reactionCount#6fb250d1 flags:# chosen:flags.0?true reaction:string count:int = ReactionCount;
|
||||
reactionCount#a3d1cb80 flags:# chosen_order:flags.0?int reaction:Reaction count:int = ReactionCount;
|
||||
messageReactions#4f2b9479 flags:# min:flags.0?true can_see_list:flags.2?true results:Vector<ReactionCount> recent_reactions:flags.1?Vector<MessagePeerReaction> = MessageReactions;
|
||||
messages.messageReactionsList#31bd492d flags:# count:int reactions:Vector<MessagePeerReaction> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = messages.MessageReactionsList;
|
||||
availableReaction#c077ec01 flags:# inactive:flags.0?true premium:flags.2?true reaction:string title:string static_icon:Document appear_animation:Document select_animation:Document activate_animation:Document effect_animation:Document around_animation:flags.1?Document center_icon:flags.1?Document = AvailableReaction;
|
||||
@ -973,7 +981,7 @@ messages.availableReactionsNotModified#9f071957 = messages.AvailableReactions;
|
||||
messages.availableReactions#768e3aad hash:int reactions:Vector<AvailableReaction> = messages.AvailableReactions;
|
||||
messages.translateNoResult#67ca4737 = messages.TranslatedText;
|
||||
messages.translateResultText#a214f7d0 text:string = messages.TranslatedText;
|
||||
messagePeerReaction#51b67eff flags:# big:flags.0?true unread:flags.1?true peer_id:Peer reaction:string = MessagePeerReaction;
|
||||
messagePeerReaction#b156fe9c flags:# big:flags.0?true unread:flags.1?true peer_id:Peer reaction:Reaction = MessagePeerReaction;
|
||||
groupCallStreamChannel#80eb48af channel:int scale:int last_timestamp_ms:long = GroupCallStreamChannel;
|
||||
phone.groupCallStreamChannels#d0e482b2 channels:Vector<GroupCallStreamChannel> = phone.GroupCallStreamChannels;
|
||||
phone.groupCallStreamRtmpUrl#2dbf3432 url:string key:string = phone.GroupCallStreamRtmpUrl;
|
||||
@ -1006,17 +1014,40 @@ inputInvoiceMessage#c5b56859 peer:InputPeer msg_id:int = InputInvoice;
|
||||
inputInvoiceSlug#c326caef slug:string = InputInvoice;
|
||||
payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice;
|
||||
messages.transcribedAudio#93752c52 flags:# pending:flags.0?true transcription_id:long text:string = messages.TranscribedAudio;
|
||||
help.premiumPromo#8a4f3c29 status_text:string status_entities:Vector<MessageEntity> video_sections:Vector<string> videos:Vector<Document> currency:string monthly_amount:long users:Vector<User> = help.PremiumPromo;
|
||||
help.premiumPromo#5334759c status_text:string status_entities:Vector<MessageEntity> video_sections:Vector<string> videos:Vector<Document> period_options:Vector<PremiumSubscriptionOption> users:Vector<User> = help.PremiumPromo;
|
||||
inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true = InputStorePaymentPurpose;
|
||||
inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose;
|
||||
premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption;
|
||||
paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod;
|
||||
emojiStatusEmpty#2de11aae = EmojiStatus;
|
||||
emojiStatus#929b619d document_id:long = EmojiStatus;
|
||||
emojiStatusUntil#fa30a8c7 document_id:long until:int = EmojiStatus;
|
||||
account.emojiStatusesNotModified#d08ce645 = account.EmojiStatuses;
|
||||
account.emojiStatuses#90c467d1 hash:long statuses:Vector<EmojiStatus> = account.EmojiStatuses;
|
||||
reactionEmpty#79f5d419 = Reaction;
|
||||
reactionEmoji#1b2286b8 emoticon:string = Reaction;
|
||||
reactionCustomEmoji#8935fc73 document_id:long = Reaction;
|
||||
chatReactionsNone#eafc32bc = ChatReactions;
|
||||
chatReactionsAll#52928bca flags:# allow_custom:flags.0?true = ChatReactions;
|
||||
chatReactionsSome#661d4037 reactions:Vector<Reaction> = ChatReactions;
|
||||
messages.reactionsNotModified#b06fdbdf = messages.Reactions;
|
||||
messages.reactions#eafdf716 hash:long reactions:Vector<Reaction> = messages.Reactions;
|
||||
emailVerifyPurposeLoginSetup#4345be73 phone_number:string phone_code_hash:string = EmailVerifyPurpose;
|
||||
emailVerifyPurposeLoginChange#527d22eb = EmailVerifyPurpose;
|
||||
emailVerifyPurposePassport#bbf51685 = EmailVerifyPurpose;
|
||||
emailVerificationCode#922e55a9 code:string = EmailVerification;
|
||||
emailVerificationGoogle#db909ec2 token:string = EmailVerification;
|
||||
emailVerificationApple#96d074fd token:string = EmailVerification;
|
||||
account.emailVerified#2b96cd1b email:string = 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;
|
||||
sendAsPeer#b81c7034 flags:# premium_required:flags.0?true peer:Peer = SendAsPeer;
|
||||
---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;
|
||||
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
|
||||
auth.sendCode#a677244f phone_number:string api_id:int api_hash:string settings:CodeSettings = auth.SentCode;
|
||||
auth.signUp#80eee427 phone_number:string phone_code_hash:string first_name:string last_name:string = auth.Authorization;
|
||||
auth.signIn#bcd51581 phone_number:string phone_code_hash:string phone_code:string = auth.Authorization;
|
||||
auth.signIn#8d52a951 flags:# phone_number:string phone_code_hash:string phone_code:flags.0?string email_verification:flags.1?EmailVerification = auth.Authorization;
|
||||
auth.logOut#3e72ba19 = auth.LoggedOut;
|
||||
auth.resetAuthorizations#9fab0d1a = Bool;
|
||||
auth.exportAuthorization#e5bfffcd dc_id:int = auth.ExportedAuthorization;
|
||||
@ -1087,8 +1118,8 @@ messages.deleteHistory#b08f922a flags:# just_clear:flags.0?true revoke:flags.1?t
|
||||
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
|
||||
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
|
||||
messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool;
|
||||
messages.sendMessage#d9d75a4 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.sendMedia#e25ff8e0 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.sendMessage#d9d75a4 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.sendMedia#e25ff8e0 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.forwardMessages#cc30290b flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
||||
messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings;
|
||||
@ -1137,7 +1168,7 @@ messages.getFavedStickers#4f1aaa9 hash:long = messages.FavedStickers;
|
||||
messages.faveSticker#b9ffc55b id:InputDocument unfave:Bool = Bool;
|
||||
messages.getUnreadMentions#46578472 peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||
messages.readMentions#f0189d3 peer:InputPeer = messages.AffectedHistory;
|
||||
messages.sendMultiMedia#f803138f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.sendMultiMedia#f803138f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.searchStickerSets#35705b8a flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets;
|
||||
messages.markDialogUnread#c286d98f flags:# unread:flags.0?true peer:InputDialogPeer = Bool;
|
||||
messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true unpin:flags.1?true pm_oneside:flags.2?true peer:InputPeer id:int = Updates;
|
||||
@ -1172,20 +1203,20 @@ messages.hideChatJoinRequest#7fe7e815 flags:# approved:flags.0?true peer:InputPe
|
||||
messages.hideAllChatJoinRequests#e085f4ea flags:# approved:flags.0?true peer:InputPeer link:flags.1?string = Updates;
|
||||
messages.toggleNoForwards#b11eafa2 peer:InputPeer enabled:Bool = Updates;
|
||||
messages.saveDefaultSendAs#ccfddf96 peer:InputPeer send_as:InputPeer = Bool;
|
||||
messages.sendReaction#25690ce4 flags:# big:flags.1?true peer:InputPeer msg_id:int reaction:flags.0?string = Updates;
|
||||
messages.sendReaction#d30d78d4 flags:# big:flags.1?true add_to_recent:flags.2?true peer:InputPeer msg_id:int reaction:flags.0?Vector<Reaction> = Updates;
|
||||
messages.getMessagesReactions#8bba90e6 peer:InputPeer id:Vector<int> = Updates;
|
||||
messages.getMessageReactionsList#e0ee6b77 flags:# peer:InputPeer id:int reaction:flags.0?string offset:flags.1?string limit:int = messages.MessageReactionsList;
|
||||
messages.setChatAvailableReactions#14050ea6 peer:InputPeer available_reactions:Vector<string> = Updates;
|
||||
messages.getMessageReactionsList#461b3f48 flags:# peer:InputPeer id:int reaction:flags.0?Reaction offset:flags.1?string limit:int = messages.MessageReactionsList;
|
||||
messages.setChatAvailableReactions#feb16771 peer:InputPeer available_reactions:ChatReactions = Updates;
|
||||
messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions;
|
||||
messages.setDefaultReaction#d960c4d4 reaction:string = Bool;
|
||||
messages.setDefaultReaction#4f47a016 reaction:Reaction = Bool;
|
||||
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.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
|
||||
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
|
||||
messages.toggleBotInAttachMenu#1aee33af bot:InputUser enabled:Bool = Bool;
|
||||
messages.requestWebView#91b15831 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 send_as:flags.13?InputPeer = WebViewResult;
|
||||
messages.requestWebView#fc87a53c flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to_msg_id:flags.0?int send_as:flags.13?InputPeer = WebViewResult;
|
||||
messages.prolongWebView#ea5fbcce flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int send_as:flags.13?InputPeer = Bool;
|
||||
messages.requestSimpleWebView#6abb2f73 flags:# bot:InputUser url:string theme_params:flags.0?DataJSON = SimpleWebViewResult;
|
||||
messages.requestSimpleWebView#299bec8e flags:# bot:InputUser url:string theme_params:flags.0?DataJSON platform:string = 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;
|
||||
messages.transcribeAudio#269e9a49 peer:InputPeer msg_id:int = messages.TranscribedAudio;
|
||||
|
||||
@ -80,7 +80,7 @@ storage.fileMp4#b3cea0e4 = storage.FileType;
|
||||
storage.fileWebp#1081464c = storage.FileType;
|
||||
|
||||
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 bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?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#5d99adee flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus = User;
|
||||
|
||||
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
||||
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
|
||||
@ -98,8 +98,8 @@ 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 join_to_send:flags.28?true join_request:flags.29?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;
|
||||
|
||||
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#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;
|
||||
chatFull#c9d31138 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions = ChatFull;
|
||||
channelFull#f2355507 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel: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?ChatReactions = ChatFull;
|
||||
|
||||
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
|
||||
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
|
||||
@ -294,7 +294,7 @@ updateChannelMessageViews#f226ac08 channel_id:long id:int views:int = Update;
|
||||
updateChatParticipantAdmin#d7ca61a2 chat_id:long user_id:long is_admin:Bool version:int = Update;
|
||||
updateNewStickerSet#688a30aa stickerset:messages.StickerSet = Update;
|
||||
updateStickerSetsOrder#bb2d201 flags:# masks:flags.0?true emojis:flags.1?true order:Vector<long> = Update;
|
||||
updateStickerSets#43ae3dec = Update;
|
||||
updateStickerSets#31c24808 flags:# masks:flags.0?true emojis:flags.1?true = Update;
|
||||
updateSavedGifs#9375341e = Update;
|
||||
updateBotInlineQuery#496f379c flags:# query_id:long user_id:long query:string geo:flags.0?GeoPoint peer_type:flags.1?InlineQueryPeerType offset:string = Update;
|
||||
updateBotInlineSend#12f12a07 flags:# user_id:long query:string geo:flags.0?GeoPoint id:string msg_id:flags.1?InputBotInlineMessageID = Update;
|
||||
@ -363,6 +363,10 @@ updateBotMenuButton#14b85813 bot_id:long button:BotMenuButton = Update;
|
||||
updateSavedRingtones#74d8be99 = Update;
|
||||
updateTranscribedAudio#84cd5a flags:# pending:flags.0?true peer:Peer msg_id:int transcription_id:long text:string = Update;
|
||||
updateReadFeaturedEmojiStickers#fb4c496c = Update;
|
||||
updateUserEmojiStatus#28373599 user_id:long emoji_status:EmojiStatus = Update;
|
||||
updateRecentEmojiStatuses#30f443db = Update;
|
||||
updateRecentReactions#6f7863f4 = Update;
|
||||
updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?true stickerset:long = Update;
|
||||
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
|
||||
@ -389,7 +393,7 @@ upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes
|
||||
|
||||
dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true this_port_only:flags.5?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption;
|
||||
|
||||
config#330b4067 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true pfs_enabled:flags.13?true force_try_ipv6:flags.14?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int pinned_infolder_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int = Config;
|
||||
config#232566ac flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true pfs_enabled:flags.13?true force_try_ipv6:flags.14?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int pinned_infolder_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int reactions_default:flags.15?Reaction = Config;
|
||||
|
||||
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
|
||||
|
||||
@ -527,7 +531,7 @@ authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true pa
|
||||
|
||||
account.authorizations#4bff8ea0 authorization_ttl_days:int authorizations:Vector<Authorization> = account.Authorizations;
|
||||
|
||||
account.password#185b184f flags:# has_recovery:flags.0?true has_secure_values:flags.1?true has_password:flags.2?true current_algo:flags.2?PasswordKdfAlgo srp_B:flags.2?bytes srp_id:flags.2?long hint:flags.3?string email_unconfirmed_pattern:flags.4?string new_algo:PasswordKdfAlgo new_secure_algo:SecurePasswordKdfAlgo secure_random:bytes pending_reset_date:flags.5?int = account.Password;
|
||||
account.password#957b50fb flags:# has_recovery:flags.0?true has_secure_values:flags.1?true has_password:flags.2?true current_algo:flags.2?PasswordKdfAlgo srp_B:flags.2?bytes srp_id:flags.2?long hint:flags.3?string email_unconfirmed_pattern:flags.4?string new_algo:PasswordKdfAlgo new_secure_algo:SecurePasswordKdfAlgo secure_random:bytes pending_reset_date:flags.5?int login_email_pattern:flags.6?string = account.Password;
|
||||
|
||||
account.passwordSettings#9a5c33e5 flags:# email:flags.0?string secure_settings:flags.1?SecureSecretSettings = account.PasswordSettings;
|
||||
|
||||
@ -551,6 +555,8 @@ inputStickerSetAnimatedEmoji#28703c8 = InputStickerSet;
|
||||
inputStickerSetDice#e67f520e emoticon:string = InputStickerSet;
|
||||
inputStickerSetAnimatedEmojiAnimations#cde3739 = InputStickerSet;
|
||||
inputStickerSetPremiumGifts#c88b3b02 = InputStickerSet;
|
||||
inputStickerSetEmojiGenericAnimations#4c4d4ce = InputStickerSet;
|
||||
inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet;
|
||||
|
||||
stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true emojis:flags.7?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet;
|
||||
|
||||
@ -686,6 +692,8 @@ auth.sentCodeTypeSms#c000bba2 length:int = auth.SentCodeType;
|
||||
auth.sentCodeTypeCall#5353e5a7 length:int = auth.SentCodeType;
|
||||
auth.sentCodeTypeFlashCall#ab03c6d9 pattern:string = auth.SentCodeType;
|
||||
auth.sentCodeTypeMissedCall#82006484 prefix:string length:int = auth.SentCodeType;
|
||||
auth.sentCodeTypeEmailCode#5a159841 flags:# apple_signin_allowed:flags.0?true google_signin_allowed:flags.1?true email_pattern:string length:int next_phone_login_date:flags.2?int = auth.SentCodeType;
|
||||
auth.sentCodeTypeSetUpEmailRequired#a5491dea flags:# apple_signin_allowed:flags.0?true google_signin_allowed:flags.1?true = auth.SentCodeType;
|
||||
|
||||
messages.botCallbackAnswer#36585ea4 flags:# alert:flags.1?true has_url:flags.3?true native_ui:flags.4?true message:flags.0?string url:flags.2?string cache_time:int = messages.BotCallbackAnswer;
|
||||
|
||||
@ -820,7 +828,7 @@ inputWebDocument#9bed434d url:string size:int mime_type:string attributes:Vector
|
||||
|
||||
inputWebFileLocation#c239d686 url:string access_hash:long = InputWebFileLocation;
|
||||
inputWebFileGeoPointLocation#9f2221c9 geo_point:InputGeoPoint access_hash:long w:int h:int zoom:int scale:int = InputWebFileLocation;
|
||||
inputWebFileAudioAlbumThumbLocation#f46fe924 flags:# document:flags.0?InputDocument title:flags.1?string performer:flags.1?string = InputWebFileLocation;
|
||||
inputWebFileAudioAlbumThumbLocation#f46fe924 flags:# small:flags.2?true document:flags.0?InputDocument title:flags.1?string performer:flags.1?string = InputWebFileLocation;
|
||||
|
||||
upload.webFile#21e753bc size:int mime_type:string file_type:storage.FileType mtime:int bytes:bytes = upload.WebFile;
|
||||
|
||||
@ -912,7 +920,7 @@ channelAdminLogEventActionChangeHistoryTTL#6e941a38 prev_value:int new_value:int
|
||||
channelAdminLogEventActionParticipantJoinByRequest#afb6144a invite:ExportedChatInvite approved_by:long = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionToggleNoForwards#cb2ac766 new_value:Bool = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionSendMessage#278f2868 message:Message = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeAvailableReactions#9cf7f76a prev_value:Vector<string> new_value:Vector<string> = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeAvailableReactions#be4e0ef8 prev_value:ChatReactions new_value:ChatReactions = ChannelAdminLogEventAction;
|
||||
|
||||
channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
|
||||
|
||||
@ -1289,7 +1297,7 @@ searchResultPosition#7f648b67 msg_id:int date:int offset:int = SearchResultsPosi
|
||||
|
||||
messages.searchResultsPositions#53b22baf count:int positions:Vector<SearchResultsPosition> = messages.SearchResultsPositions;
|
||||
|
||||
channels.sendAsPeers#8356cda9 peers:Vector<Peer> chats:Vector<Chat> users:Vector<User> = channels.SendAsPeers;
|
||||
channels.sendAsPeers#f496b0c6 peers:Vector<SendAsPeer> chats:Vector<Chat> users:Vector<User> = channels.SendAsPeers;
|
||||
|
||||
users.userFull#3b6d152e full_user:UserFull chats:Vector<Chat> users:Vector<User> = users.UserFull;
|
||||
|
||||
@ -1297,7 +1305,7 @@ messages.peerSettings#6880b94d settings:PeerSettings chats:Vector<Chat> users:Ve
|
||||
|
||||
auth.loggedOut#c3a2835f flags:# future_auth_token:flags.0?bytes = auth.LoggedOut;
|
||||
|
||||
reactionCount#6fb250d1 flags:# chosen:flags.0?true reaction:string count:int = ReactionCount;
|
||||
reactionCount#a3d1cb80 flags:# chosen_order:flags.0?int reaction:Reaction count:int = ReactionCount;
|
||||
|
||||
messageReactions#4f2b9479 flags:# min:flags.0?true can_see_list:flags.2?true results:Vector<ReactionCount> recent_reactions:flags.1?Vector<MessagePeerReaction> = MessageReactions;
|
||||
|
||||
@ -1311,7 +1319,7 @@ messages.availableReactions#768e3aad hash:int reactions:Vector<AvailableReaction
|
||||
messages.translateNoResult#67ca4737 = messages.TranslatedText;
|
||||
messages.translateResultText#a214f7d0 text:string = messages.TranslatedText;
|
||||
|
||||
messagePeerReaction#51b67eff flags:# big:flags.0?true unread:flags.1?true peer_id:Peer reaction:string = MessagePeerReaction;
|
||||
messagePeerReaction#b156fe9c flags:# big:flags.0?true unread:flags.1?true peer_id:Peer reaction:Reaction = MessagePeerReaction;
|
||||
|
||||
groupCallStreamChannel#80eb48af channel:int scale:int last_timestamp_ms:long = GroupCallStreamChannel;
|
||||
|
||||
@ -1364,7 +1372,7 @@ payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice;
|
||||
|
||||
messages.transcribedAudio#93752c52 flags:# pending:flags.0?true transcription_id:long text:string = messages.TranscribedAudio;
|
||||
|
||||
help.premiumPromo#8a4f3c29 status_text:string status_entities:Vector<MessageEntity> video_sections:Vector<string> videos:Vector<Document> currency:string monthly_amount:long users:Vector<User> = help.PremiumPromo;
|
||||
help.premiumPromo#5334759c status_text:string status_entities:Vector<MessageEntity> video_sections:Vector<string> videos:Vector<Document> period_options:Vector<PremiumSubscriptionOption> users:Vector<User> = help.PremiumPromo;
|
||||
|
||||
inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true = InputStorePaymentPurpose;
|
||||
inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose;
|
||||
@ -1373,6 +1381,39 @@ premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_ur
|
||||
|
||||
paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod;
|
||||
|
||||
emojiStatusEmpty#2de11aae = EmojiStatus;
|
||||
emojiStatus#929b619d document_id:long = EmojiStatus;
|
||||
emojiStatusUntil#fa30a8c7 document_id:long until:int = EmojiStatus;
|
||||
|
||||
account.emojiStatusesNotModified#d08ce645 = account.EmojiStatuses;
|
||||
account.emojiStatuses#90c467d1 hash:long statuses:Vector<EmojiStatus> = account.EmojiStatuses;
|
||||
|
||||
reactionEmpty#79f5d419 = Reaction;
|
||||
reactionEmoji#1b2286b8 emoticon:string = Reaction;
|
||||
reactionCustomEmoji#8935fc73 document_id:long = Reaction;
|
||||
|
||||
chatReactionsNone#eafc32bc = ChatReactions;
|
||||
chatReactionsAll#52928bca flags:# allow_custom:flags.0?true = ChatReactions;
|
||||
chatReactionsSome#661d4037 reactions:Vector<Reaction> = ChatReactions;
|
||||
|
||||
messages.reactionsNotModified#b06fdbdf = messages.Reactions;
|
||||
messages.reactions#eafdf716 hash:long reactions:Vector<Reaction> = messages.Reactions;
|
||||
|
||||
emailVerifyPurposeLoginSetup#4345be73 phone_number:string phone_code_hash:string = EmailVerifyPurpose;
|
||||
emailVerifyPurposeLoginChange#527d22eb = EmailVerifyPurpose;
|
||||
emailVerifyPurposePassport#bbf51685 = EmailVerifyPurpose;
|
||||
|
||||
emailVerificationCode#922e55a9 code:string = EmailVerification;
|
||||
emailVerificationGoogle#db909ec2 token:string = EmailVerification;
|
||||
emailVerificationApple#96d074fd token:string = EmailVerification;
|
||||
|
||||
account.emailVerified#2b96cd1b email:string = 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;
|
||||
|
||||
sendAsPeer#b81c7034 flags:# premium_required:flags.0?true peer:Peer = SendAsPeer;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@ -1385,7 +1426,7 @@ invokeWithTakeout#aca9fd2e {X:Type} takeout_id:long query:!X = X;
|
||||
|
||||
auth.sendCode#a677244f phone_number:string api_id:int api_hash:string settings:CodeSettings = auth.SentCode;
|
||||
auth.signUp#80eee427 phone_number:string phone_code_hash:string first_name:string last_name:string = auth.Authorization;
|
||||
auth.signIn#bcd51581 phone_number:string phone_code_hash:string phone_code:string = auth.Authorization;
|
||||
auth.signIn#8d52a951 flags:# phone_number:string phone_code_hash:string phone_code:flags.0?string email_verification:flags.1?EmailVerification = auth.Authorization;
|
||||
auth.logOut#3e72ba19 = auth.LoggedOut;
|
||||
auth.resetAuthorizations#9fab0d1a = Bool;
|
||||
auth.exportAuthorization#e5bfffcd dc_id:int = auth.ExportedAuthorization;
|
||||
@ -1441,8 +1482,8 @@ account.getAuthorizationForm#a929597a bot_id:long scope:string public_key:string
|
||||
account.acceptAuthorization#f3ed4c73 bot_id:long scope:string public_key:string value_hashes:Vector<SecureValueHash> credentials:SecureCredentialsEncrypted = Bool;
|
||||
account.sendVerifyPhoneCode#a5a356f9 phone_number:string settings:CodeSettings = auth.SentCode;
|
||||
account.verifyPhone#4dd3a7f6 phone_number:string phone_code_hash:string phone_code:string = Bool;
|
||||
account.sendVerifyEmailCode#7011509f email:string = account.SentEmailCode;
|
||||
account.verifyEmail#ecba39db email:string code:string = Bool;
|
||||
account.sendVerifyEmailCode#98e037bb purpose:EmailVerifyPurpose email:string = account.SentEmailCode;
|
||||
account.verifyEmail#32da4cf purpose:EmailVerifyPurpose verification:EmailVerification = account.EmailVerified;
|
||||
account.initTakeoutSession#8ef3eab0 flags:# contacts:flags.0?true message_users:flags.1?true message_chats:flags.2?true message_megagroups:flags.3?true message_channels:flags.4?true files:flags.5?true file_max_size:flags.5?long = account.Takeout;
|
||||
account.finishTakeoutSession#1d2652ee flags:# success:flags.0?true = Bool;
|
||||
account.confirmPasswordEmail#8fdf1920 code:string = Bool;
|
||||
@ -1479,6 +1520,10 @@ account.changeAuthorizationSettings#40f48462 flags:# hash:long encrypted_request
|
||||
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;
|
||||
account.updateEmojiStatus#fbd3de6b emoji_status:EmojiStatus = Bool;
|
||||
account.getDefaultEmojiStatuses#d6753386 hash:long = account.EmojiStatuses;
|
||||
account.getRecentEmojiStatuses#f578105 hash:long = account.EmojiStatuses;
|
||||
account.clearRecentEmojiStatuses#18201aae = Bool;
|
||||
|
||||
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
||||
users.getFullUser#b60f5918 id:InputUser = users.UserFull;
|
||||
@ -1515,8 +1560,8 @@ messages.deleteHistory#b08f922a flags:# just_clear:flags.0?true revoke:flags.1?t
|
||||
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
|
||||
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
|
||||
messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool;
|
||||
messages.sendMessage#d9d75a4 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.sendMedia#e25ff8e0 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.sendMessage#d9d75a4 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.sendMedia#e25ff8e0 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.forwardMessages#cc30290b flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
||||
messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings;
|
||||
@ -1596,7 +1641,7 @@ messages.faveSticker#b9ffc55b id:InputDocument unfave:Bool = Bool;
|
||||
messages.getUnreadMentions#46578472 peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||
messages.readMentions#f0189d3 peer:InputPeer = messages.AffectedHistory;
|
||||
messages.getRecentLocations#702a40e0 peer:InputPeer limit:int hash:long = messages.Messages;
|
||||
messages.sendMultiMedia#f803138f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.sendMultiMedia#f803138f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile;
|
||||
messages.searchStickerSets#35705b8a flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets;
|
||||
messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
|
||||
@ -1655,12 +1700,12 @@ messages.hideChatJoinRequest#7fe7e815 flags:# approved:flags.0?true peer:InputPe
|
||||
messages.hideAllChatJoinRequests#e085f4ea flags:# approved:flags.0?true peer:InputPeer link:flags.1?string = Updates;
|
||||
messages.toggleNoForwards#b11eafa2 peer:InputPeer enabled:Bool = Updates;
|
||||
messages.saveDefaultSendAs#ccfddf96 peer:InputPeer send_as:InputPeer = Bool;
|
||||
messages.sendReaction#25690ce4 flags:# big:flags.1?true peer:InputPeer msg_id:int reaction:flags.0?string = Updates;
|
||||
messages.sendReaction#d30d78d4 flags:# big:flags.1?true add_to_recent:flags.2?true peer:InputPeer msg_id:int reaction:flags.0?Vector<Reaction> = Updates;
|
||||
messages.getMessagesReactions#8bba90e6 peer:InputPeer id:Vector<int> = Updates;
|
||||
messages.getMessageReactionsList#e0ee6b77 flags:# peer:InputPeer id:int reaction:flags.0?string offset:flags.1?string limit:int = messages.MessageReactionsList;
|
||||
messages.setChatAvailableReactions#14050ea6 peer:InputPeer available_reactions:Vector<string> = Updates;
|
||||
messages.getMessageReactionsList#461b3f48 flags:# peer:InputPeer id:int reaction:flags.0?Reaction offset:flags.1?string limit:int = messages.MessageReactionsList;
|
||||
messages.setChatAvailableReactions#feb16771 peer:InputPeer available_reactions:ChatReactions = Updates;
|
||||
messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions;
|
||||
messages.setDefaultReaction#d960c4d4 reaction:string = Bool;
|
||||
messages.setDefaultReaction#4f47a016 reaction:Reaction = Bool;
|
||||
messages.translateText#24ce6dee flags:# peer:flags.0?InputPeer msg_id:flags.0?int text:flags.1?string from_lang:flags.2?string to_lang:string = messages.TranslatedText;
|
||||
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;
|
||||
@ -1668,9 +1713,9 @@ messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = mes
|
||||
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
|
||||
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
|
||||
messages.toggleBotInAttachMenu#1aee33af bot:InputUser enabled:Bool = Bool;
|
||||
messages.requestWebView#91b15831 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 send_as:flags.13?InputPeer = WebViewResult;
|
||||
messages.requestWebView#fc87a53c flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to_msg_id:flags.0?int send_as:flags.13?InputPeer = WebViewResult;
|
||||
messages.prolongWebView#ea5fbcce flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int send_as:flags.13?InputPeer = Bool;
|
||||
messages.requestSimpleWebView#6abb2f73 flags:# bot:InputUser url:string theme_params:flags.0?DataJSON = SimpleWebViewResult;
|
||||
messages.requestSimpleWebView#299bec8e flags:# bot:InputUser url:string theme_params:flags.0?DataJSON platform:string = 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;
|
||||
messages.transcribeAudio#269e9a49 peer:InputPeer msg_id:int = messages.TranscribedAudio;
|
||||
@ -1678,6 +1723,10 @@ messages.rateTranscribedAudio#7f1d072f peer:InputPeer msg_id:int transcription_i
|
||||
messages.getCustomEmojiDocuments#d9ab0f54 document_id:Vector<long> = Vector<Document>;
|
||||
messages.getEmojiStickers#fbfca18f hash:long = messages.AllStickers;
|
||||
messages.getFeaturedEmojiStickers#ecf6736 hash:long = messages.FeaturedStickers;
|
||||
messages.reportReaction#3f64c076 peer:InputPeer id:int reaction_peer:InputPeer = Bool;
|
||||
messages.getTopReactions#bb8125ba limit:int hash:long = messages.Reactions;
|
||||
messages.getRecentReactions#39461db2 limit:int hash:long = messages.Reactions;
|
||||
messages.clearRecentReactions#9dfeefb4 = Bool;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||
@ -1784,7 +1833,6 @@ payments.exportInvoice#f91b065 invoice_media:InputMedia = payments.ExportedInvoi
|
||||
payments.assignAppStoreTransaction#80ed747d receipt:bytes purpose:InputStorePaymentPurpose = Updates;
|
||||
payments.assignPlayMarketTransaction#dffd50d3 receipt:DataJSON purpose:InputStorePaymentPurpose = Updates;
|
||||
payments.canPurchasePremium#9fc19eb6 purpose:InputStorePaymentPurpose = Bool;
|
||||
payments.requestRecurringPayment#146e958d user_id:InputUser recurring_init_charge:string invoice_media:InputMedia = Updates;
|
||||
|
||||
stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true animated:flags.1?true videos:flags.4?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> software:flags.3?string = messages.StickerSet;
|
||||
stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
|
||||
@ -1840,3 +1888,5 @@ stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph;
|
||||
stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel = stats.MegagroupStats;
|
||||
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
||||
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats;
|
||||
|
||||
// LAYER 145
|
||||
|
||||
@ -90,9 +90,10 @@ class RLottie {
|
||||
private container: HTMLDivElement,
|
||||
private tgsUrl: string,
|
||||
private params: Params = {},
|
||||
private onLoad?: () => void,
|
||||
private customColor?: [number, number, number],
|
||||
private onLoad?: () => void,
|
||||
private onEnded?: (isDestroyed?: boolean) => void,
|
||||
private onLoop?: () => void,
|
||||
) {
|
||||
this.initContainer();
|
||||
this.initConfig();
|
||||
@ -135,6 +136,10 @@ class RLottie {
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
setNoLoop(noLoop: boolean) {
|
||||
this.params.noLoop = noLoop;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.isDestroyed = true;
|
||||
this.pause();
|
||||
@ -355,6 +360,7 @@ class RLottie {
|
||||
this.onEnded?.();
|
||||
return false;
|
||||
}
|
||||
this.onLoop?.();
|
||||
|
||||
this.approxFrameIndex = 0;
|
||||
|
||||
@ -366,6 +372,7 @@ class RLottie {
|
||||
this.onEnded?.();
|
||||
return false;
|
||||
}
|
||||
this.onLoop?.();
|
||||
|
||||
this.approxFrameIndex = this.framesCount! - 1;
|
||||
|
||||
|
||||
@ -183,6 +183,7 @@ $color-message-reaction-own-hover: #b5e0a4;
|
||||
--messages-container-width: 45.5rem;
|
||||
--right-column-width: 26.5rem;
|
||||
--header-height: 3.5rem;
|
||||
--custom-emoji-size: 1.5rem;
|
||||
|
||||
--symbol-menu-width: 26.25rem;
|
||||
--symbol-menu-height: 23.25rem;
|
||||
|
||||
@ -74,7 +74,7 @@ function transition(t: number) {
|
||||
return 1 - ((1 - t) ** 3.5);
|
||||
}
|
||||
|
||||
function hexToRgb(hex: string): RGBAColor {
|
||||
export function hexToRgb(hex: string): RGBAColor {
|
||||
const result = HEX_COLOR_REGEX.exec(hex)!;
|
||||
|
||||
return {
|
||||
|
||||
@ -2,13 +2,13 @@ import type { 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');
|
||||
const secondaryBgColor = getPropertyWrapped(style, '--color-background-secondary');
|
||||
const backgroundColor = getPropertyHexColor(style, '--color-background')!;
|
||||
const textColor = getPropertyHexColor(style, '--color-text')!;
|
||||
const buttonColor = getPropertyHexColor(style, '--color-primary')!;
|
||||
const buttonTextColor = getPropertyHexColor(style, '--color-white')!;
|
||||
const linkColor = getPropertyHexColor(style, '--color-links')!;
|
||||
const hintColor = getPropertyHexColor(style, '--color-text-secondary')!;
|
||||
const secondaryBgColor = getPropertyHexColor(style, '--color-background-secondary')!;
|
||||
return {
|
||||
bg_color: backgroundColor,
|
||||
text_color: textColor,
|
||||
@ -24,12 +24,13 @@ export function validateHexColor(color: string) {
|
||||
return /^#[0-9A-F]{6}$/i.test(color);
|
||||
}
|
||||
|
||||
function getPropertyWrapped(style: CSSStyleDeclaration, property: string) {
|
||||
export function getPropertyHexColor(style: CSSStyleDeclaration, property: string) {
|
||||
const value = style.getPropertyValue(property);
|
||||
return wrapColor(value.trim());
|
||||
if (!value) return undefined;
|
||||
return prepareHexColor(value.trim());
|
||||
}
|
||||
|
||||
function wrapColor(color: string) {
|
||||
function prepareHexColor(color: string) {
|
||||
if (validateHexColor(color)) return color;
|
||||
return `#${color.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/)!
|
||||
.slice(1)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user