Layer 174 (#4277)
This commit is contained in:
parent
2bed347f28
commit
033f8d4791
@ -66,6 +66,8 @@ export interface GramJsAppConfig extends LimitsConfig {
|
||||
story_expire_period: number;
|
||||
story_viewers_expire_period: number;
|
||||
stories_changelog_user_id?: number;
|
||||
// Boosts
|
||||
group_transcribe_level_min?: number;
|
||||
}
|
||||
|
||||
function buildEmojiSounds(appConfig: GramJsAppConfig) {
|
||||
@ -134,5 +136,6 @@ export function buildAppConfig(json: GramJs.TypeJSONValue, hash: number): ApiApp
|
||||
storyExpirePeriod: appConfig.story_expire_period ?? STORY_EXPIRE_PERIOD,
|
||||
storyViewersExpirePeriod: appConfig.story_viewers_expire_period ?? STORY_VIEWERS_EXPIRE_PERIOD,
|
||||
storyChangelogUserId: appConfig.stories_changelog_user_id?.toString() ?? SERVICE_NOTIFICATIONS_USER_ID,
|
||||
groupTranscribeLevelMin: appConfig.group_transcribe_level_min,
|
||||
};
|
||||
}
|
||||
|
||||
@ -62,8 +62,9 @@ function buildApiChatFieldsFromPeerEntity(
|
||||
const color = ('color' in peerEntity && peerEntity.color) ? buildApiPeerColor(peerEntity.color) : undefined;
|
||||
const emojiStatus = ('emojiStatus' in peerEntity && peerEntity.emojiStatus)
|
||||
? buildApiEmojiStatus(peerEntity.emojiStatus) : undefined;
|
||||
const boostLevel = ('level' in peerEntity) ? peerEntity.level : undefined;
|
||||
|
||||
return omitUndefined({
|
||||
return omitUndefined<PeerEntityApiChatFields>({
|
||||
isMin,
|
||||
hasPrivateLink,
|
||||
isSignaturesShown,
|
||||
@ -93,6 +94,7 @@ function buildApiChatFieldsFromPeerEntity(
|
||||
maxStoryId,
|
||||
hasStories: Boolean(maxStoryId) && !storiesUnavailable,
|
||||
emojiStatus,
|
||||
boostLevel,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -159,7 +159,7 @@ export type UniversalMessage = (
|
||||
'out' | 'message' | 'entities' | 'fromId' | 'peerId' | 'fwdFrom' | 'replyTo' | 'replyMarkup' | 'post' |
|
||||
'media' | 'action' | 'views' | 'editDate' | 'editHide' | 'mediaUnread' | 'groupedId' | 'mentioned' | 'viaBotId' |
|
||||
'replies' | 'fromScheduled' | 'postAuthor' | 'noforwards' | 'reactions' | 'forwards' | 'silent' | 'pinned' |
|
||||
'savedPeerId'
|
||||
'savedPeerId' | 'fromBoostsApplied'
|
||||
)>
|
||||
);
|
||||
|
||||
@ -197,10 +197,11 @@ export function buildApiMessageWithChatId(
|
||||
const isForwardingAllowed = !mtpMessage.noforwards;
|
||||
const emojiOnlyCount = getEmojiOnlyCountForMessage(content, groupedId);
|
||||
const hasComments = mtpMessage.replies?.comments;
|
||||
const senderBoosts = mtpMessage.fromBoostsApplied;
|
||||
|
||||
const savedPeerId = mtpMessage.savedPeerId && getApiChatIdFromMtpPeer(mtpMessage.savedPeerId);
|
||||
|
||||
return omitUndefined({
|
||||
return omitUndefined<ApiMessage>({
|
||||
id: mtpMessage.id,
|
||||
chatId,
|
||||
isOutgoing,
|
||||
@ -237,7 +238,8 @@ export function buildApiMessageWithChatId(
|
||||
isForwardingAllowed,
|
||||
hasComments,
|
||||
savedPeerId,
|
||||
} satisfies ApiMessage);
|
||||
senderBoosts,
|
||||
});
|
||||
}
|
||||
|
||||
export function buildMessageDraft(draft: GramJs.TypeDraftMessage): ApiDraft | undefined {
|
||||
@ -288,7 +290,7 @@ function buildApiReplyInfo(replyHeader: GramJs.TypeMessageReplyHeader): ApiReply
|
||||
if (replyHeader instanceof GramJs.MessageReplyStoryHeader) {
|
||||
return {
|
||||
type: 'story',
|
||||
userId: replyHeader.userId.toString(),
|
||||
peerId: getApiChatIdFromMtpPeer(replyHeader.peer),
|
||||
storyId: replyHeader.storyId,
|
||||
};
|
||||
}
|
||||
@ -563,6 +565,20 @@ function buildAction(
|
||||
amount = action.winnersCount;
|
||||
pluralValue = action.winnersCount;
|
||||
}
|
||||
} else if (action instanceof GramJs.MessageActionBoostApply) {
|
||||
type = 'chatBoost';
|
||||
if (action.boosts === 1) {
|
||||
text = senderId === currentUserId ? 'BoostingBoostsGroupByYouServiceMsg' : 'BoostingBoostsGroupByUserServiceMsg';
|
||||
translationValues.push('%action_origin%');
|
||||
} else {
|
||||
text = senderId === currentUserId ? 'BoostingBoostsGroupByYouServiceMsgCount'
|
||||
: 'BoostingBoostsGroupByUserServiceMsgCount';
|
||||
translationValues.push(action.boosts.toString());
|
||||
if (senderId !== currentUserId) {
|
||||
translationValues.unshift('%action_origin%');
|
||||
}
|
||||
pluralValue = action.boosts;
|
||||
}
|
||||
} else {
|
||||
text = 'ChatList.UnsupportedMessage';
|
||||
}
|
||||
@ -901,7 +917,7 @@ function buildReplyInfo(inputInfo: ApiInputReplyInfo, isForum?: boolean): ApiRep
|
||||
if (inputInfo.type === 'story') {
|
||||
return {
|
||||
type: 'story',
|
||||
userId: inputInfo.userId,
|
||||
peerId: inputInfo.peerId,
|
||||
storyId: inputInfo.storyId,
|
||||
};
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import type {
|
||||
ApiMediaArea,
|
||||
ApiMediaAreaCoordinates,
|
||||
ApiStealthMode,
|
||||
ApiStory,
|
||||
ApiStoryForwardInfo,
|
||||
ApiStoryView,
|
||||
ApiStoryViews,
|
||||
@ -46,7 +47,7 @@ export function buildApiStory(peerId: string, story: GramJs.TypeStoryItem): ApiT
|
||||
edited, pinned, expireDate, id, date, caption,
|
||||
entities, media, privacy, views,
|
||||
public: isPublic, noforwards, closeFriends, contacts, selectedContacts,
|
||||
mediaAreas, sentReaction, out, fwdFrom,
|
||||
mediaAreas, sentReaction, out, fwdFrom, fromId,
|
||||
} = story;
|
||||
|
||||
const content: MediaContent = {
|
||||
@ -57,38 +58,38 @@ export function buildApiStory(peerId: string, story: GramJs.TypeStoryItem): ApiT
|
||||
content.text = buildMessageTextContent(caption, entities);
|
||||
}
|
||||
|
||||
return {
|
||||
return omitUndefined<ApiStory>({
|
||||
id,
|
||||
peerId,
|
||||
date,
|
||||
expireDate,
|
||||
content,
|
||||
...(isPublic && { isPublic }),
|
||||
...(edited && { isEdited: true }),
|
||||
...(pinned && { isPinned: true }),
|
||||
...(contacts && { isForContacts: true }),
|
||||
...(selectedContacts && { isForSelectedContacts: true }),
|
||||
...(closeFriends && { isForCloseFriends: true }),
|
||||
...(noforwards && { noForwards: true }),
|
||||
...(views && { views: buildApiStoryViews(views) }),
|
||||
...(out && { isOut: true }),
|
||||
...(privacy && { visibility: buildPrivacyRules(privacy) }),
|
||||
...(mediaAreas && { mediaAreas: mediaAreas.map(buildApiMediaArea).filter(Boolean) }),
|
||||
...(sentReaction && { sentReaction: buildApiReaction(sentReaction) }),
|
||||
...(fwdFrom && { forwardInfo: buildApiStoryForwardInfo(fwdFrom) }),
|
||||
};
|
||||
isPublic,
|
||||
isEdited: edited,
|
||||
isPinned: pinned,
|
||||
isForContacts: contacts,
|
||||
isForSelectedContacts: selectedContacts,
|
||||
isForCloseFriends: closeFriends,
|
||||
noForwards: noforwards,
|
||||
views: views && buildApiStoryViews(views),
|
||||
isOut: out,
|
||||
visibility: privacy && buildPrivacyRules(privacy),
|
||||
mediaAreas: mediaAreas?.map(buildApiMediaArea).filter(Boolean),
|
||||
sentReaction: sentReaction && buildApiReaction(sentReaction),
|
||||
forwardInfo: fwdFrom && buildApiStoryForwardInfo(fwdFrom),
|
||||
fromId: fromId && getApiChatIdFromMtpPeer(fromId),
|
||||
});
|
||||
}
|
||||
|
||||
function buildApiStoryViews(views: GramJs.TypeStoryViews): ApiStoryViews | undefined {
|
||||
return {
|
||||
export function buildApiStoryViews(views: GramJs.TypeStoryViews): ApiStoryViews {
|
||||
return omitUndefined<ApiStoryViews>({
|
||||
hasViewers: views.hasViewers,
|
||||
viewsCount: views.viewsCount,
|
||||
forwardsCount: views.forwardsCount,
|
||||
reactionsCount: views.reactionsCount,
|
||||
...(views?.reactions && { reactions: views.reactions.map(buildReactionCount).filter(Boolean) }),
|
||||
...(views?.recentViewers && {
|
||||
recentViewerIds: views.recentViewers.map((viewerId) => buildApiPeerId(viewerId, 'user')),
|
||||
}),
|
||||
};
|
||||
reactions: views.reactions?.map(buildReactionCount).filter(Boolean),
|
||||
recentViewerIds: views.recentViewers?.map((viewerId) => buildApiPeerId(viewerId, 'user')),
|
||||
});
|
||||
}
|
||||
|
||||
export function buildApiStoryView(view: GramJs.TypeStoryView): ApiTypeStoryView | undefined {
|
||||
|
||||
@ -646,7 +646,7 @@ export function buildInputBotApp(app: ApiBotApp) {
|
||||
export function buildInputReplyTo(replyInfo: ApiInputReplyInfo) {
|
||||
if (replyInfo.type === 'story') {
|
||||
return new GramJs.InputReplyToStory({
|
||||
userId: buildInputPeerFromLocalDb(replyInfo.userId)!,
|
||||
peer: buildInputPeerFromLocalDb(replyInfo.peerId)!,
|
||||
storyId: replyInfo.storyId,
|
||||
});
|
||||
}
|
||||
|
||||
@ -80,7 +80,8 @@ import { invokeRequest, uploadFile } from './client';
|
||||
|
||||
type FullChatData = {
|
||||
fullInfo: ApiChatFullInfo;
|
||||
users?: ApiUser[];
|
||||
users: ApiUser[];
|
||||
chats: ApiChat[];
|
||||
userStatusesById: { [userId: string]: ApiUserStatus };
|
||||
groupCall?: Partial<ApiGroupCall>;
|
||||
membersCount?: number;
|
||||
@ -519,6 +520,7 @@ async function getFullChatInfo(chatId: string): Promise<FullChatData | undefined
|
||||
const botCommands = botInfo ? buildApiChatBotCommands(botInfo) : undefined;
|
||||
const inviteLink = exportedInvite instanceof GramJs.ChatInviteExported ? exportedInvite.link : undefined;
|
||||
const { users, userStatusesById } = buildApiUsersAndStatuses(result.users);
|
||||
const chats = result.chats.map((chat) => buildApiChatFromPreview(chat)).filter(Boolean);
|
||||
|
||||
return {
|
||||
fullInfo: {
|
||||
@ -536,6 +538,7 @@ async function getFullChatInfo(chatId: string): Promise<FullChatData | undefined
|
||||
isTranslationDisabled: translationsDisabled,
|
||||
},
|
||||
users,
|
||||
chats,
|
||||
userStatusesById,
|
||||
groupCall: call ? {
|
||||
chatId,
|
||||
@ -590,6 +593,9 @@ async function getFullChannelInfo(
|
||||
translationsDisabled,
|
||||
storiesPinnedAvailable,
|
||||
viewForumAsMessages,
|
||||
emojiset,
|
||||
boostsApplied,
|
||||
boostsUnrestrict,
|
||||
} = result.fullChat;
|
||||
|
||||
if (chatPhoto instanceof GramJs.Photo) {
|
||||
@ -608,6 +614,7 @@ async function getFullChannelInfo(
|
||||
canViewParticipants && await fetchMembers(id, accessHash, 'admin')
|
||||
) || {};
|
||||
const botCommands = botInfo ? buildApiChatBotCommands(botInfo) : undefined;
|
||||
const chats = result.chats.map((chat) => buildApiChatFromPreview(chat)).filter(Boolean);
|
||||
|
||||
if (result?.chats?.length > 1) {
|
||||
updateLocalDb(result);
|
||||
@ -662,11 +669,15 @@ async function getFullChannelInfo(
|
||||
recentRequesterIds: recentRequesters?.map((userId) => buildApiPeerId(userId, 'user')),
|
||||
statisticsDcId: statsDc,
|
||||
stickerSet: stickerset ? buildStickerSet(stickerset) : undefined,
|
||||
emojiSet: emojiset ? buildStickerSet(emojiset) : undefined,
|
||||
areParticipantsHidden: participantsHidden,
|
||||
isTranslationDisabled: translationsDisabled,
|
||||
hasPinnedStories: Boolean(storiesPinnedAvailable),
|
||||
boostsApplied,
|
||||
boostsToUnrestrict: boostsUnrestrict,
|
||||
},
|
||||
users: [...(users || []), ...(bannedUsers || []), ...(adminUsers || [])],
|
||||
chats,
|
||||
userStatusesById: statusesById,
|
||||
groupCall: call ? {
|
||||
chatId: id,
|
||||
|
||||
@ -21,6 +21,7 @@ import {
|
||||
buildApiStealthMode,
|
||||
buildApiStory,
|
||||
buildApiStoryView,
|
||||
buildApiStoryViews,
|
||||
} from '../apiBuilders/stories';
|
||||
import { buildApiUser } from '../apiBuilders/users';
|
||||
import {
|
||||
@ -300,6 +301,33 @@ export async function fetchStoryViewList({
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchStoriesViews({
|
||||
peer,
|
||||
storyIds,
|
||||
}: {
|
||||
peer: ApiPeer;
|
||||
storyIds: number[];
|
||||
}) {
|
||||
const result = await invokeRequest(new GramJs.stories.GetStoriesViews({
|
||||
peer: buildInputPeer(peer.id, peer.accessHash),
|
||||
id: storyIds,
|
||||
}));
|
||||
|
||||
if (!result?.views[0]) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
addEntitiesToLocalDb(result.users);
|
||||
|
||||
const views = buildApiStoryViews(result.views[0]);
|
||||
const users = result.users.map(buildApiUser).filter(Boolean);
|
||||
|
||||
return {
|
||||
views,
|
||||
users,
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchStoryLink({ peer, storyId }: { peer: ApiPeer ; storyId: number }) {
|
||||
const result = await invokeRequest(new GramJs.stories.ExportStoryLink({
|
||||
peer: buildInputPeer(peer.id, peer.accessHash),
|
||||
|
||||
@ -52,6 +52,7 @@ export interface ApiChat {
|
||||
listedTopicIds?: number[];
|
||||
topicsCount?: number;
|
||||
orderedPinnedTopicIds?: number[];
|
||||
boostLevel?: number;
|
||||
|
||||
// Calls
|
||||
isCallActive?: boolean;
|
||||
@ -128,10 +129,14 @@ export interface ApiChatFullInfo {
|
||||
requestsPending?: number;
|
||||
statisticsDcId?: number;
|
||||
stickerSet?: ApiStickerSet;
|
||||
emojiSet?: ApiStickerSet;
|
||||
profilePhoto?: ApiPhoto;
|
||||
areParticipantsHidden?: boolean;
|
||||
isTranslationDisabled?: true;
|
||||
hasPinnedStories?: boolean;
|
||||
|
||||
boostsApplied?: number;
|
||||
boostsToUnrestrict?: number;
|
||||
}
|
||||
|
||||
export interface ApiChatMember {
|
||||
|
||||
@ -298,6 +298,7 @@ export interface ApiAction {
|
||||
| 'topicCreate'
|
||||
| 'suggestProfilePhoto'
|
||||
| 'joinedChannel'
|
||||
| 'chatBoost'
|
||||
| 'other';
|
||||
photo?: ApiPhoto;
|
||||
amount?: number;
|
||||
@ -356,7 +357,7 @@ export interface ApiMessageReplyInfo {
|
||||
|
||||
export interface ApiStoryReplyInfo {
|
||||
type: 'story';
|
||||
userId: string;
|
||||
peerId: string;
|
||||
storyId: number;
|
||||
}
|
||||
|
||||
@ -370,7 +371,7 @@ export interface ApiInputMessageReplyInfo {
|
||||
|
||||
export interface ApiInputStoryReplyInfo {
|
||||
type: 'story';
|
||||
userId: string;
|
||||
peerId: string;
|
||||
storyId: number;
|
||||
}
|
||||
|
||||
@ -539,6 +540,7 @@ export interface ApiMessage {
|
||||
hasComments?: boolean;
|
||||
readDate?: number;
|
||||
savedPeerId?: string;
|
||||
senderBoosts?: number;
|
||||
}
|
||||
|
||||
export interface ApiReactions {
|
||||
|
||||
@ -197,6 +197,7 @@ export interface ApiAppConfig {
|
||||
storyExpirePeriod: number;
|
||||
storyViewersExpirePeriod: number;
|
||||
storyChangelogUserId: string;
|
||||
groupTranscribeLevelMin?: number;
|
||||
}
|
||||
|
||||
export interface ApiConfig {
|
||||
|
||||
@ -23,9 +23,11 @@ export interface ApiStory {
|
||||
sentReaction?: ApiReaction;
|
||||
mediaAreas?: ApiMediaArea[];
|
||||
forwardInfo?: ApiStoryForwardInfo;
|
||||
fromId?: string;
|
||||
}
|
||||
|
||||
export interface ApiStoryViews {
|
||||
hasViewers?: true;
|
||||
viewsCount?: number;
|
||||
forwardsCount?: number;
|
||||
reactionsCount?: number;
|
||||
|
||||
1
src/assets/font-icons/boost-outline.svg
Normal file
1
src/assets/font-icons/boost-outline.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="none"><path fill="#000" d="m20.9 10.884.862-5.46c.635-4.018-4.62-6.107-6.918-2.75L6.311 15.146c-1.732 2.533.081 5.97 3.15 5.97H11.1l-.862 5.46c-.635 4.019 4.62 6.108 6.918 2.75l8.533-12.47c1.732-2.533-.081-5.97-3.15-5.97zm-3.807-6.67c.657-.96 2.158-.363 1.977.786l-1.16 7.35a1.09 1.09 0 0 0 1.076 1.26h3.553c.877 0 1.395.982.9 1.705l-8.532 12.471c-.657.96-2.158.362-1.977-.786l.08-.511 1.08-6.838a1.09 1.09 0 0 0-1.076-1.26H9.46a1.09 1.09 0 0 1-.9-1.706z" style="stroke-width:1.36275"/></svg>
|
||||
|
After Width: | Height: | Size: 561 B |
@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="M19.322 13.194c-.69 0-1.216-.616-1.109-1.298l1.5-9.498c.187-1.182-1.36-1.797-2.035-.809L7.1 17.05c-.51.746.023 1.757.926 1.757h4.652c.69 0 1.216.616 1.109 1.298l-1.5 9.498c-.187 1.182 1.36 1.797 2.035.809L24.9 14.95a1.122 1.122 0 0 0-.926-1.757Z" style="stroke-width:1.68365"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="M19.341 13.175a1.129 1.129 0 0 1-1.115-1.303l1.512-9.56c.182-1.192-1.374-1.81-2.052-.817L7.038 17.06a1.129 1.129 0 0 0 .934 1.765h4.682c.696 0 1.225.62 1.116 1.306l-1.507 9.56c-.19 1.19 1.366 1.808 2.047.814l10.65-15.562a1.129 1.129 0 0 0-.93-1.768z" style="stroke-width:2.60715"/></svg>
|
||||
|
Before Width: | Height: | Size: 355 B After Width: | Height: | Size: 359 B |
1
src/assets/font-icons/boosts.svg
Normal file
1
src/assets/font-icons/boosts.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="m22.105 16.416-3.054 4.283-1.477 8.992c-.195 1.189 1.425 1.807 2.134.814l11.086-15.562a1.175 1.129 0 0 0-.972-1.768h-4.878a1.175 1.129 0 0 1-1.162-1.303l1.57-9.56c.197-1.192-1.423-1.81-2.132-.817l-6.463 9.073h2.134c3.13 0 4.978 3.366 3.21 5.848zm-3.065-3.233c.855.1 1.33 1.05.825 1.76L8.78 30.505c-.706.993-2.33.375-2.131-.814l1.569-9.56a1.175 1.129 0 0 0-1.162-1.304H2.18a1.175 1.129 0 0 1-.972-1.77L12.294 1.495c.709-.993 2.33-.375 2.134.816l-1.572 9.558c-.111.686.44 1.306 1.162 1.306h4.875z" style="stroke-width:2.66026"/></svg>
|
||||
|
After Width: | Height: | Size: 604 B |
@ -207,6 +207,8 @@ const Avatar: FC<OwnProps> = ({
|
||||
content = getFirstLetters(text, 2);
|
||||
}
|
||||
|
||||
const isRoundedRect = isForum && !((withStory || withStorySolid) && peer?.hasStories);
|
||||
|
||||
const fullClassName = buildClassName(
|
||||
`Avatar size-${size}`,
|
||||
className,
|
||||
@ -216,7 +218,7 @@ const Avatar: FC<OwnProps> = ({
|
||||
isAnonymousForwards && 'anonymous-forwards',
|
||||
isDeleted && 'deleted-account',
|
||||
isReplies && 'replies-bot-account',
|
||||
isForum && 'forum',
|
||||
isRoundedRect && 'forum',
|
||||
((withStory && peer?.hasStories) || forPremiumPromo) && 'with-story-circle',
|
||||
withStorySolid && peer?.hasStories && 'with-story-solid',
|
||||
withStorySolid && (peer?.hasUnreadStories || forceUnreadStorySolid) && 'has-unread-story',
|
||||
|
||||
@ -2,9 +2,9 @@ import type { FC } from '../../lib/teact/teact';
|
||||
import React, {
|
||||
memo, useMemo, useRef, useState,
|
||||
} from '../../lib/teact/teact';
|
||||
import { getActions } from '../../global';
|
||||
import { getActions, getGlobal } from '../../global';
|
||||
|
||||
import type { ApiChat, ApiTopic } from '../../api/types';
|
||||
import type { ApiTopic } from '../../api/types';
|
||||
import type { ThreadId } from '../../types';
|
||||
|
||||
import { CHAT_HEIGHT_PX } from '../../config';
|
||||
@ -35,7 +35,6 @@ import './ChatOrUserPicker.scss';
|
||||
export type OwnProps = {
|
||||
currentUserId?: string;
|
||||
chatOrUserIds: string[];
|
||||
chatsById?: Record<string, ApiChat>;
|
||||
isOpen: boolean;
|
||||
searchPlaceholder: string;
|
||||
search: string;
|
||||
@ -55,7 +54,6 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
||||
isOpen,
|
||||
currentUserId,
|
||||
chatOrUserIds,
|
||||
chatsById,
|
||||
search,
|
||||
searchPlaceholder,
|
||||
className,
|
||||
@ -89,7 +87,11 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
||||
useInputFocusOnOpen(topicSearchRef, isOpen && activeKey === TOPIC_LIST_SLIDE);
|
||||
|
||||
const [topicIds, topics] = useMemo(() => {
|
||||
const topicsResult = forumId ? chatsById?.[forumId].topics : undefined;
|
||||
const global = getGlobal();
|
||||
const chatsById = global.chats.byId;
|
||||
const chatFullInfoById = global.chats.fullInfoById;
|
||||
|
||||
const topicsResult = forumId ? chatsById[forumId].topics : undefined;
|
||||
if (!topicsResult) {
|
||||
return [undefined, undefined];
|
||||
}
|
||||
@ -99,7 +101,7 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
||||
const result = topicsResult
|
||||
? Object.values(topicsResult).reduce((acc, topic) => {
|
||||
if (
|
||||
getCanPostInChat(chatsById![forumId!], topic.id)
|
||||
getCanPostInChat(chatsById[forumId!], topic.id, undefined, chatFullInfoById[forumId!])
|
||||
&& (!searchTitle || topic.title.toLowerCase().includes(searchTitle))
|
||||
) {
|
||||
acc[topic.id] = topic;
|
||||
@ -110,7 +112,7 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
||||
: topicsResult;
|
||||
|
||||
return [Object.keys(result).map(Number), result];
|
||||
}, [chatsById, forumId, topicSearch]);
|
||||
}, [forumId, topicSearch]);
|
||||
|
||||
const handleHeaderBackClick = useLastCallback(() => {
|
||||
setForumId(undefined);
|
||||
@ -127,8 +129,10 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
||||
|
||||
const handleKeyDown = useKeyboardListNavigation(containerRef, isOpen, (index) => {
|
||||
if (viewportIds && viewportIds.length > 0) {
|
||||
const chatsById = getGlobal().chats.byId;
|
||||
|
||||
const chatId = viewportIds[index === -1 ? 0 : index];
|
||||
const chat = chatsById?.[chatId];
|
||||
const chat = chatsById[chatId];
|
||||
if (chat?.isForum) {
|
||||
if (!chat.topics) loadTopics({ chatId });
|
||||
setForumId(chatId);
|
||||
@ -145,6 +149,7 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
||||
}, '.ListItem-button', true);
|
||||
|
||||
const handleClick = useLastCallback((e: React.MouseEvent, chatId: string) => {
|
||||
const chatsById = getGlobal().chats.byId;
|
||||
const chat = chatsById?.[chatId];
|
||||
if (chat?.isForum) {
|
||||
if (!chat.topics) loadTopics({ chatId });
|
||||
|
||||
@ -14,7 +14,6 @@ import type {
|
||||
ApiBotMenuButton,
|
||||
ApiChat,
|
||||
ApiChatFullInfo,
|
||||
ApiChatMember,
|
||||
ApiFormattedText,
|
||||
ApiMessage,
|
||||
ApiMessageEntity,
|
||||
@ -191,6 +190,7 @@ type StateProps =
|
||||
isOnActiveTab: boolean;
|
||||
editingMessage?: ApiMessage;
|
||||
chat?: ApiChat;
|
||||
chatFullInfo?: ApiChatFullInfo;
|
||||
draft?: ApiDraft;
|
||||
replyToTopic?: ApiTopic;
|
||||
currentMessageList?: MessageList;
|
||||
@ -210,7 +210,6 @@ type StateProps =
|
||||
canScheduleUntilOnline?: boolean;
|
||||
stickersForEmoji?: ApiSticker[];
|
||||
customEmojiForEmoji?: ApiSticker[];
|
||||
groupChatMembers?: ApiChatMember[];
|
||||
currentUserId?: string;
|
||||
currentUser?: ApiUser;
|
||||
recentEmojis: string[];
|
||||
@ -224,7 +223,6 @@ type StateProps =
|
||||
inlineBots?: Record<string, false | InlineBotSettings>;
|
||||
botCommands?: ApiBotCommand[] | false;
|
||||
botMenuButton?: ApiBotMenuButton;
|
||||
chatBotCommands?: ApiBotCommand[];
|
||||
sendAsUser?: ApiUser;
|
||||
sendAsChat?: ApiChat;
|
||||
sendAsId?: string;
|
||||
@ -293,6 +291,7 @@ const Composer: FC<OwnProps & StateProps> = ({
|
||||
messageListType,
|
||||
draft,
|
||||
chat,
|
||||
chatFullInfo,
|
||||
replyToTopic,
|
||||
isForCurrentMessageList,
|
||||
isCurrentUserPremium,
|
||||
@ -312,7 +311,6 @@ const Composer: FC<OwnProps & StateProps> = ({
|
||||
withScheduledButton,
|
||||
stickersForEmoji,
|
||||
customEmojiForEmoji,
|
||||
groupChatMembers,
|
||||
topInlineBotIds,
|
||||
currentUserId,
|
||||
currentUser,
|
||||
@ -326,7 +324,6 @@ const Composer: FC<OwnProps & StateProps> = ({
|
||||
inlineBots,
|
||||
isInlineBotLoading,
|
||||
botCommands,
|
||||
chatBotCommands,
|
||||
sendAsUser,
|
||||
sendAsChat,
|
||||
sendAsId,
|
||||
@ -405,6 +402,9 @@ const Composer: FC<OwnProps & StateProps> = ({
|
||||
|
||||
const canMediaBeReplaced = editingMessage && hasReplaceableMedia(editingMessage);
|
||||
|
||||
const { emojiSet, members: groupChatMembers, botCommands: chatBotCommands } = chatFullInfo || {};
|
||||
const chatEmojiSetId = emojiSet?.id;
|
||||
|
||||
const isSentStoryReactionHeart = sentStoryReaction && 'emoticon' in sentStoryReaction
|
||||
? sentStoryReaction.emoticon === HEART_REACTION.emoticon : false;
|
||||
|
||||
@ -457,8 +457,8 @@ const Composer: FC<OwnProps & StateProps> = ({
|
||||
canSendStickers, canSendGifs, canAttachMedia, canAttachPolls, canAttachEmbedLinks,
|
||||
canSendVoices, canSendPlainText, canSendAudios, canSendVideos, canSendPhotos, canSendDocuments,
|
||||
} = useMemo(
|
||||
() => getAllowedAttachmentOptions(chat, isChatWithBot, isInStoryViewer),
|
||||
[chat, isChatWithBot, isInStoryViewer],
|
||||
() => getAllowedAttachmentOptions(chat, chatFullInfo, isChatWithBot, isInStoryViewer),
|
||||
[chat, chatFullInfo, isChatWithBot, isInStoryViewer],
|
||||
);
|
||||
|
||||
const isComposerBlocked = !canSendPlainText && !editingMessage;
|
||||
@ -1088,7 +1088,8 @@ const Composer: FC<OwnProps & StateProps> = ({
|
||||
}, [handleFileSelect, requestedDraftFiles, resetOpenChatWithDraft]);
|
||||
|
||||
const handleCustomEmojiSelect = useLastCallback((emoji: ApiSticker, inInputId?: string) => {
|
||||
if (!emoji.isFree && !isCurrentUserPremium && !isChatWithSelf) {
|
||||
const emojiSetId = 'id' in emoji.stickerSetInfo && emoji.stickerSetInfo.id;
|
||||
if (!emoji.isFree && !isCurrentUserPremium && !isChatWithSelf && emojiSetId !== chatEmojiSetId) {
|
||||
showCustomEmojiPremiumNotification();
|
||||
return;
|
||||
}
|
||||
@ -2027,7 +2028,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
pollModal: tabState.pollModal,
|
||||
stickersForEmoji: global.stickers.forEmoji.stickers,
|
||||
customEmojiForEmoji: global.customEmojis.forEmoji.stickers,
|
||||
groupChatMembers: chatFullInfo?.members,
|
||||
chatFullInfo,
|
||||
topInlineBotIds: global.topInlineBots?.userIds,
|
||||
currentUserId,
|
||||
currentUser,
|
||||
@ -2040,7 +2041,6 @@ export default memo(withGlobal<OwnProps>(
|
||||
emojiKeywords: emojiKeywords?.keywords,
|
||||
inlineBots: tabState.inlineBots.byUsername,
|
||||
isInlineBotLoading: tabState.inlineBots.isLoading,
|
||||
chatBotCommands: chatFullInfo?.botCommands,
|
||||
botCommands: chatBotFullInfo ? (chatBotFullInfo.botInfo?.commands || false) : undefined,
|
||||
botMenuButton: chatBotFullInfo?.botInfo?.menuButton,
|
||||
sendAsUser,
|
||||
|
||||
@ -10,10 +10,8 @@ import type {
|
||||
import type { StickerSetOrReactionsSetOrRecent } from '../../types';
|
||||
|
||||
import {
|
||||
CHAT_STICKER_SET_ID,
|
||||
FAVORITE_SYMBOL_SET_ID,
|
||||
POPULAR_SYMBOL_SET_ID,
|
||||
PREMIUM_STICKER_SET_ID,
|
||||
RECENT_SYMBOL_SET_ID,
|
||||
SLIDE_TRANSITION_DURATION,
|
||||
STICKER_PICKER_MAX_SHARED_COVERS,
|
||||
@ -23,6 +21,7 @@ import {
|
||||
import { isSameReaction } from '../../global/helpers';
|
||||
import {
|
||||
selectCanPlayAnimatedEmojis,
|
||||
selectChatFullInfo,
|
||||
selectIsAlwaysHighPriorityEmoji,
|
||||
selectIsChatWithSelf,
|
||||
selectIsCurrentUserPremium,
|
||||
@ -44,6 +43,7 @@ import { useStickerPickerObservers } from './hooks/useStickerPickerObservers';
|
||||
import StickerSetCover from '../middle/composer/StickerSetCover';
|
||||
import Button from '../ui/Button';
|
||||
import Loading from '../ui/Loading';
|
||||
import Icon from './Icon';
|
||||
import StickerButton from './StickerButton';
|
||||
import StickerSet from './StickerSet';
|
||||
|
||||
@ -73,6 +73,7 @@ type StateProps = {
|
||||
customEmojisById?: Record<string, ApiSticker>;
|
||||
recentCustomEmojiIds?: string[];
|
||||
recentStatusEmojis?: ApiSticker[];
|
||||
chatEmojiSetId?: string;
|
||||
topReactions?: ApiReaction[];
|
||||
recentReactions?: ApiReaction[];
|
||||
defaultTagReactions?: ApiReaction[];
|
||||
@ -97,8 +98,6 @@ const STICKER_SET_IDS_WITH_COVER = new Set([
|
||||
RECENT_SYMBOL_SET_ID,
|
||||
FAVORITE_SYMBOL_SET_ID,
|
||||
POPULAR_SYMBOL_SET_ID,
|
||||
CHAT_STICKER_SET_ID,
|
||||
PREMIUM_STICKER_SET_ID,
|
||||
]);
|
||||
|
||||
const CustomEmojiPicker: FC<OwnProps & StateProps> = ({
|
||||
@ -112,6 +111,7 @@ const CustomEmojiPicker: FC<OwnProps & StateProps> = ({
|
||||
selectedReactionIds,
|
||||
recentStatusEmojis,
|
||||
stickerSetsById,
|
||||
chatEmojiSetId,
|
||||
topReactions,
|
||||
recentReactions,
|
||||
availableReactions,
|
||||
@ -250,7 +250,12 @@ const CustomEmojiPicker: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
}
|
||||
|
||||
const setIdsToDisplay = unique((addedCustomEmojiIds || []).concat(customEmojiFeaturedIds || []));
|
||||
const userSetIds = [...(addedCustomEmojiIds || [])];
|
||||
if (chatEmojiSetId) {
|
||||
userSetIds.unshift(chatEmojiSetId);
|
||||
}
|
||||
|
||||
const setIdsToDisplay = unique(userSetIds.concat(customEmojiFeaturedIds || []));
|
||||
|
||||
const setsToDisplay = Object.values(pickTruthy(stickerSetsById, setIdsToDisplay));
|
||||
|
||||
@ -261,7 +266,7 @@ const CustomEmojiPicker: FC<OwnProps & StateProps> = ({
|
||||
}, [
|
||||
addedCustomEmojiIds, isReactionPicker, isStatusPicker, withDefaultTopicIcons, recentCustomEmojis,
|
||||
customEmojiFeaturedIds, stickerSetsById, topReactions, availableReactions, lang, recentReactions,
|
||||
defaultStatusIconsId, defaultTopicIconsId, isSavedMessages, defaultTagReactions,
|
||||
defaultStatusIconsId, defaultTopicIconsId, isSavedMessages, defaultTagReactions, chatEmojiSetId,
|
||||
]);
|
||||
|
||||
const noPopulatedSets = useMemo(() => (
|
||||
@ -327,7 +332,7 @@ const CustomEmojiPicker: FC<OwnProps & StateProps> = ({
|
||||
onClick={() => selectStickerSet(isRecent ? 0 : index)}
|
||||
>
|
||||
{isRecent ? (
|
||||
<i className="icon icon-recent" />
|
||||
<Icon name="recent" />
|
||||
) : (
|
||||
<StickerSetCover
|
||||
stickerSet={stickerSet as ApiStickerSet}
|
||||
@ -407,6 +412,7 @@ const CustomEmojiPicker: FC<OwnProps & StateProps> = ({
|
||||
{allSets.map((stickerSet, i) => {
|
||||
const shouldHideHeader = stickerSet.id === TOP_SYMBOL_SET_ID
|
||||
|| (stickerSet.id === RECENT_SYMBOL_SET_ID && (withDefaultTopicIcons || isStatusPicker));
|
||||
const isChatEmojiSet = stickerSet.id === chatEmojiSetId;
|
||||
|
||||
return (
|
||||
<StickerSet
|
||||
@ -425,6 +431,7 @@ const CustomEmojiPicker: FC<OwnProps & StateProps> = ({
|
||||
shouldHideHeader={shouldHideHeader}
|
||||
withDefaultTopicIcon={withDefaultTopicIcons && stickerSet.id === RECENT_SYMBOL_SET_ID}
|
||||
withDefaultStatusIcon={isStatusPicker && stickerSet.id === RECENT_SYMBOL_SET_ID}
|
||||
isChatEmojiSet={isChatEmojiSet}
|
||||
isCurrentUserPremium={isCurrentUserPremium}
|
||||
selectedReactionIds={selectedReactionIds}
|
||||
availableReactions={availableReactions}
|
||||
@ -466,6 +473,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
} = global;
|
||||
|
||||
const isSavedMessages = Boolean(chatId && selectIsChatWithSelf(global, chatId));
|
||||
const chatFullInfo = chatId ? selectChatFullInfo(global, chatId) : undefined;
|
||||
|
||||
return {
|
||||
customEmojisById: !isStatusPicker ? customEmojisById : undefined,
|
||||
@ -481,6 +489,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
defaultStatusIconsId: global.defaultStatusIconsId,
|
||||
topReactions: isReactionPicker ? topReactions : undefined,
|
||||
recentReactions: isReactionPicker ? recentReactions : undefined,
|
||||
chatEmojiSetId: chatFullInfo?.emojiSet?.id,
|
||||
availableReactions: isReactionPicker ? availableReactions : undefined,
|
||||
defaultTagReactions: isReactionPicker ? defaultTags : undefined,
|
||||
};
|
||||
|
||||
@ -2,7 +2,7 @@ import type { FC } from '../../lib/teact/teact';
|
||||
import React, { memo, useMemo, useState } from '../../lib/teact/teact';
|
||||
import { getGlobal, withGlobal } from '../../global';
|
||||
|
||||
import type { ApiChat, ApiChatType } from '../../api/types';
|
||||
import type { ApiChatType } from '../../api/types';
|
||||
import type { ThreadId } from '../../types';
|
||||
import { MAIN_THREAD_ID } from '../../api/types';
|
||||
|
||||
@ -35,7 +35,6 @@ export type OwnProps = {
|
||||
|
||||
type StateProps = {
|
||||
currentUserId?: string;
|
||||
chatsById: Record<string, ApiChat>;
|
||||
activeListIds?: string[];
|
||||
archivedListIds?: string[];
|
||||
pinnedIds?: string[];
|
||||
@ -45,7 +44,6 @@ type StateProps = {
|
||||
const RecipientPicker: FC<OwnProps & StateProps> = ({
|
||||
isOpen,
|
||||
currentUserId,
|
||||
chatsById,
|
||||
activeListIds,
|
||||
archivedListIds,
|
||||
pinnedIds,
|
||||
@ -71,6 +69,8 @@ const RecipientPicker: FC<OwnProps & StateProps> = ({
|
||||
// No need for expensive global updates on users, so we avoid them
|
||||
const global = getGlobal();
|
||||
const usersById = global.users.byId;
|
||||
const chatsById = global.chats.byId;
|
||||
const chatFullInfoById = global.chats.fullInfoById;
|
||||
|
||||
const chatIds = [
|
||||
...(activeListIds || []),
|
||||
@ -80,7 +80,7 @@ const RecipientPicker: FC<OwnProps & StateProps> = ({
|
||||
const user = usersById[id];
|
||||
if (user && isDeletedUser(user)) return false;
|
||||
|
||||
return chat && getCanPostInChat(chat, MAIN_THREAD_ID);
|
||||
return chat && getCanPostInChat(chat, MAIN_THREAD_ID, undefined, chatFullInfoById[id]);
|
||||
});
|
||||
|
||||
const sorted = sortChatIds(unique([
|
||||
@ -89,7 +89,7 @@ const RecipientPicker: FC<OwnProps & StateProps> = ({
|
||||
]), undefined, priorityIds);
|
||||
|
||||
return filterChatIdsByType(global, sorted, filter);
|
||||
}, [pinnedIds, currentUserId, activeListIds, search, archivedListIds, lang, chatsById, contactIds, filter, isOpen]);
|
||||
}, [pinnedIds, currentUserId, activeListIds, search, archivedListIds, lang, contactIds, filter, isOpen]);
|
||||
|
||||
const renderingIds = useCurrentOrPrev(ids, true)!;
|
||||
|
||||
@ -98,7 +98,6 @@ const RecipientPicker: FC<OwnProps & StateProps> = ({
|
||||
isOpen={isOpen}
|
||||
className={className}
|
||||
chatOrUserIds={renderingIds}
|
||||
chatsById={chatsById}
|
||||
searchPlaceholder={searchPlaceholder}
|
||||
search={search}
|
||||
onSearchChange={setSearch}
|
||||
@ -114,7 +113,6 @@ export default memo(withGlobal<OwnProps>(
|
||||
(global): StateProps => {
|
||||
const {
|
||||
chats: {
|
||||
byId: chatsById,
|
||||
listIds,
|
||||
orderedPinnedIds,
|
||||
},
|
||||
@ -122,7 +120,6 @@ export default memo(withGlobal<OwnProps>(
|
||||
} = global;
|
||||
|
||||
return {
|
||||
chatsById,
|
||||
activeListIds: listIds.active,
|
||||
archivedListIds: listIds.archived,
|
||||
pinnedIds: orderedPinnedIds.active,
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
vertical-align: bottom;
|
||||
align-self: center;
|
||||
justify-self: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sticker-locked {
|
||||
|
||||
@ -38,6 +38,7 @@ type OwnProps<T> = {
|
||||
canViewSet?: boolean;
|
||||
isSelected?: boolean;
|
||||
isCurrentUserPremium?: boolean;
|
||||
shouldIgnorePremium?: boolean;
|
||||
sharedCanvasRef?: React.RefObject<HTMLCanvasElement>;
|
||||
withTranslucentThumb?: boolean;
|
||||
forcePlayback?: boolean;
|
||||
@ -76,6 +77,7 @@ const StickerButton = <T extends number | ApiSticker | ApiBotInlineMediaResult |
|
||||
observeIntersectionForShowing,
|
||||
isSelected,
|
||||
isCurrentUserPremium,
|
||||
shouldIgnorePremium,
|
||||
noShowPremium,
|
||||
sharedCanvasRef,
|
||||
withTranslucentThumb,
|
||||
@ -101,7 +103,7 @@ const StickerButton = <T extends number | ApiSticker | ApiBotInlineMediaResult |
|
||||
const {
|
||||
id, isCustomEmoji, hasEffect: isPremium, stickerSetInfo,
|
||||
} = sticker;
|
||||
const isLocked = !isCurrentUserPremium && isPremium;
|
||||
const isLocked = !isCurrentUserPremium && isPremium && !shouldIgnorePremium;
|
||||
|
||||
const isIntersecting = useIsIntersecting(ref, observeIntersection);
|
||||
const shouldLoad = isIntersecting;
|
||||
|
||||
@ -52,6 +52,8 @@ type OwnProps = {
|
||||
selectedReactionIds?: string[];
|
||||
withDefaultTopicIcon?: boolean;
|
||||
withDefaultStatusIcon?: boolean;
|
||||
isChatEmojiSet?: boolean;
|
||||
isChatStickerSet?: boolean;
|
||||
isTranslucent?: boolean;
|
||||
noContextMenus?: boolean;
|
||||
forcePlayback?: boolean;
|
||||
@ -91,6 +93,8 @@ const StickerSet: FC<OwnProps> = ({
|
||||
withDefaultTopicIcon,
|
||||
selectedReactionIds,
|
||||
withDefaultStatusIcon,
|
||||
isChatEmojiSet,
|
||||
isChatStickerSet,
|
||||
isTranslucent,
|
||||
noContextMenus,
|
||||
forcePlayback,
|
||||
@ -224,10 +228,11 @@ const StickerSet: FC<OwnProps> = ({
|
||||
}
|
||||
}, [shouldRender, loadStickers, stickerSet]);
|
||||
|
||||
const isLocked = !isSavedMessages && !isCurrentUserPremium && isPremiumSet;
|
||||
const isLocked = !isSavedMessages && !isCurrentUserPremium && isPremiumSet && !isChatEmojiSet;
|
||||
|
||||
const isInstalled = stickerSet.installedDate && !stickerSet.isArchived;
|
||||
const canCut = !isInstalled && stickerSet.id !== RECENT_SYMBOL_SET_ID && stickerSet.id !== POPULAR_SYMBOL_SET_ID;
|
||||
const canCut = !isInstalled && stickerSet.id !== RECENT_SYMBOL_SET_ID && stickerSet.id !== POPULAR_SYMBOL_SET_ID
|
||||
&& !isChatEmojiSet && !isChatStickerSet;
|
||||
const [isCut, , expand] = useFlag(canCut);
|
||||
const itemsBeforeCutout = itemsPerRow * 3 - 1;
|
||||
const totalItemsCount = withDefaultTopicIcon ? stickerSet.count + 1 : stickerSet.count;
|
||||
@ -240,7 +245,7 @@ const StickerSet: FC<OwnProps> = ({
|
||||
const favoriteStickerIdsSet = useMemo(() => (
|
||||
favoriteStickers ? new Set(favoriteStickers.map(({ id }) => id)) : undefined
|
||||
), [favoriteStickers]);
|
||||
const withAddSetButton = !shouldHideHeader && !isRecent && isEmoji && !isPopular
|
||||
const withAddSetButton = !shouldHideHeader && !isRecent && isEmoji && !isPopular && !isChatEmojiSet
|
||||
&& (!isInstalled || (!isCurrentUserPremium && !isSavedMessages));
|
||||
const addSetButtonText = useMemo(() => {
|
||||
if (isLocked) {
|
||||
@ -265,6 +270,9 @@ const StickerSet: FC<OwnProps> = ({
|
||||
<p className={buildClassName('symbol-set-name', withAddSetButton && 'symbol-set-name-external')}>
|
||||
{isLocked && <i className="symbol-set-locked-icon icon icon-lock-badge" />}
|
||||
{stickerSet.title}
|
||||
{(isChatEmojiSet || isChatStickerSet) && (
|
||||
<span className="symbol-set-chat">{lang(isChatEmojiSet ? 'GroupEmoji' : 'GroupStickers')}</span>
|
||||
)}
|
||||
{withAddSetButton && Boolean(stickerSet.stickers) && (
|
||||
<span className="symbol-set-amount">
|
||||
{lang(isEmoji ? 'EmojiCount' : 'Stickers', stickerSet.stickers.length, 'i')}
|
||||
@ -360,6 +368,7 @@ const StickerSet: FC<OwnProps> = ({
|
||||
canViewSet
|
||||
noContextMenu={noContextMenus}
|
||||
isCurrentUserPremium={isCurrentUserPremium}
|
||||
shouldIgnorePremium={isChatEmojiSet}
|
||||
sharedCanvasRef={canvasRef}
|
||||
withTranslucentThumb={isTranslucent}
|
||||
onClick={onStickerSelect}
|
||||
|
||||
@ -12,6 +12,7 @@ import { getAllowedAttachmentOptions, getCanPostInChat } from '../../global/help
|
||||
import {
|
||||
selectCanScheduleUntilOnline,
|
||||
selectChat,
|
||||
selectChatFullInfo,
|
||||
selectCurrentMessageList,
|
||||
selectIsChatWithSelf,
|
||||
selectIsCurrentUserPremium,
|
||||
@ -258,11 +259,13 @@ export default memo(withGlobal<OwnProps>(
|
||||
const currentMessageList = selectCurrentMessageList(global);
|
||||
const { chatId, threadId } = currentMessageList || {};
|
||||
const chat = chatId && selectChat(global, chatId);
|
||||
const sendOptions = chat ? getAllowedAttachmentOptions(chat) : undefined;
|
||||
const chatFullInfo = chatId ? selectChatFullInfo(global, chatId) : undefined;
|
||||
const sendOptions = chat ? getAllowedAttachmentOptions(chat, chatFullInfo) : undefined;
|
||||
const threadInfo = chatId && threadId ? selectThreadInfo(global, chatId, threadId) : undefined;
|
||||
const isMessageThread = Boolean(!threadInfo?.isCommentsInfo && threadInfo?.fromChannelId);
|
||||
const canSendStickers = Boolean(
|
||||
chat && threadId && getCanPostInChat(chat, threadId, isMessageThread) && sendOptions?.canSendStickers,
|
||||
chat && threadId && getCanPostInChat(chat, threadId, isMessageThread, chatFullInfo)
|
||||
&& sendOptions?.canSendStickers,
|
||||
);
|
||||
const isSavedMessages = Boolean(chatId) && selectIsChatWithSelf(global, chatId);
|
||||
|
||||
|
||||
@ -14,11 +14,14 @@ export function getBoostProgressInfo(boostInfo: ApiBoostsStatus, freezeOnLevelUp
|
||||
: (boosts - currentLevelBoosts) / (nextLevelBoosts - currentLevelBoosts);
|
||||
const remainingBoosts = nextLevelBoosts ? nextLevelBoosts - boosts : 0;
|
||||
|
||||
const isMaxLevel = nextLevelBoosts === undefined;
|
||||
|
||||
return {
|
||||
currentLevel,
|
||||
hasNextLevel,
|
||||
boosts,
|
||||
levelProgress,
|
||||
remainingBoosts,
|
||||
isMaxLevel,
|
||||
};
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import type { TabState } from '../../global/types';
|
||||
import { MAIN_THREAD_ID } from '../../api/types';
|
||||
|
||||
import { getCanPostInChat } from '../../global/helpers';
|
||||
import { selectChat } from '../../global/selectors';
|
||||
import { selectChat, selectChatFullInfo } from '../../global/selectors';
|
||||
|
||||
import useInterval from '../../hooks/useInterval';
|
||||
import useLang from '../../hooks/useLang';
|
||||
@ -93,7 +93,8 @@ export default memo(withGlobal<OwnProps>(
|
||||
(global, { openedGame }): StateProps => {
|
||||
const { chatId } = openedGame || {};
|
||||
const chat = chatId && selectChat(global, chatId);
|
||||
const canPost = Boolean(chat) && getCanPostInChat(chat, MAIN_THREAD_ID);
|
||||
const chatFullInfo = chatId ? selectChatFullInfo(global, chatId) : undefined;
|
||||
const canPost = Boolean(chat) && getCanPostInChat(chat, MAIN_THREAD_ID, undefined, chatFullInfo);
|
||||
|
||||
return {
|
||||
canPost,
|
||||
|
||||
@ -268,7 +268,6 @@ const Main: FC<OwnProps & StateProps> = ({
|
||||
loadDefaultTagReactions,
|
||||
loadFeaturedEmojiStickers,
|
||||
setIsElectronUpdateAvailable,
|
||||
loadPremiumSetStickers,
|
||||
loadAuthorizations,
|
||||
loadPeerColors,
|
||||
loadSavedReactionTags,
|
||||
@ -357,7 +356,6 @@ const Main: FC<OwnProps & StateProps> = ({
|
||||
if (isMasterTab && isCurrentUserPremium) {
|
||||
loadDefaultStatusIcons();
|
||||
loadRecentEmojiStatuses();
|
||||
loadPremiumSetStickers();
|
||||
}
|
||||
}, [isCurrentUserPremium, isMasterTab]);
|
||||
|
||||
|
||||
@ -67,6 +67,7 @@ interface StateProps {
|
||||
canMute?: boolean;
|
||||
canViewStatistics?: boolean;
|
||||
canViewBoosts?: boolean;
|
||||
canShowBoostModal?: boolean;
|
||||
canLeave?: boolean;
|
||||
canEnterVoiceChat?: boolean;
|
||||
canCreateVoiceChat?: boolean;
|
||||
@ -100,6 +101,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
|
||||
canMute,
|
||||
canViewStatistics,
|
||||
canViewBoosts,
|
||||
canShowBoostModal,
|
||||
canLeave,
|
||||
canEnterVoiceChat,
|
||||
canCreateVoiceChat,
|
||||
@ -433,6 +435,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
|
||||
canMute={canMute}
|
||||
canViewStatistics={canViewStatistics}
|
||||
canViewBoosts={canViewBoosts}
|
||||
canShowBoostModal={canShowBoostModal}
|
||||
canLeave={canLeave}
|
||||
canEnterVoiceChat={canEnterVoiceChat}
|
||||
canCreateVoiceChat={canCreateVoiceChat}
|
||||
@ -456,6 +459,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
}): StateProps => {
|
||||
const chat = selectChat(global, chatId);
|
||||
const isChannel = Boolean(chat && isChatChannel(chat));
|
||||
const isSuperGroup = Boolean(chat && isChatSuperGroup(chat));
|
||||
const language = selectLanguageCode(global);
|
||||
const translationLanguage = selectTranslationLanguage(global);
|
||||
const isPrivate = isUserId(chatId);
|
||||
@ -486,7 +490,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
const canStartBot = !canRestartBot && Boolean(selectIsChatBotNotStarted(global, chatId));
|
||||
const canUnblock = isUserBlocked && !bot;
|
||||
const canSubscribe = Boolean(
|
||||
(isMainThread || chat.isForum) && (isChannel || isChatSuperGroup(chat)) && chat.isNotJoined,
|
||||
(isMainThread || chat.isForum) && (isChannel || isSuperGroup) && chat.isNotJoined,
|
||||
);
|
||||
const canSearch = isMainThread || isDiscussionThread;
|
||||
const canCall = ARE_CALLS_SUPPORTED && isUserId(chat.id) && !isChatWithSelf && !bot && !chat.isSupport
|
||||
@ -498,6 +502,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
&& (chat.adminRights?.manageCall || (chat.isCreator && isChatBasicGroup(chat)));
|
||||
const canViewStatistics = isMainThread && chatFullInfo?.canViewStatistics;
|
||||
const canViewBoosts = isMainThread && isChannel && (canViewStatistics || getHasAdminRight(chat, 'postStories'));
|
||||
const canShowBoostModal = !canViewBoosts && (isSuperGroup || isChannel);
|
||||
const pendingJoinRequests = isMainThread ? chatFullInfo?.requestsPending : undefined;
|
||||
const shouldJoinToSend = Boolean(chat?.isNotJoined && chat.isJoinToSend);
|
||||
const shouldSendJoinRequest = Boolean(chat?.isNotJoined && chat.isJoinRequest);
|
||||
@ -518,6 +523,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
canMute,
|
||||
canViewStatistics,
|
||||
canViewBoosts,
|
||||
canShowBoostModal,
|
||||
canLeave,
|
||||
canEnterVoiceChat,
|
||||
canCreateVoiceChat,
|
||||
|
||||
@ -84,6 +84,7 @@ export type OwnProps = {
|
||||
canMute?: boolean;
|
||||
canViewStatistics?: boolean;
|
||||
canViewBoosts?: boolean;
|
||||
canShowBoostModal?: boolean;
|
||||
withForumActions?: boolean;
|
||||
canLeave?: boolean;
|
||||
canEnterVoiceChat?: boolean;
|
||||
@ -166,6 +167,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
isBot,
|
||||
isChatWithSelf,
|
||||
savedDialog,
|
||||
canShowBoostModal,
|
||||
onJoinRequestsClick,
|
||||
onSubscribeChannel,
|
||||
onSearchClick,
|
||||
@ -195,6 +197,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
blockUser,
|
||||
unblockUser,
|
||||
setViewForumAsMessages,
|
||||
openBoostModal,
|
||||
} = getActions();
|
||||
|
||||
const { isMobile } = useAppLayout();
|
||||
@ -346,8 +349,12 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const handleBoostClick = useLastCallback(() => {
|
||||
openBoostStatistics({ chatId });
|
||||
setShouldCloseFast(!isRightColumnShown);
|
||||
if (canViewBoosts) {
|
||||
openBoostStatistics({ chatId });
|
||||
setShouldCloseFast(!isRightColumnShown);
|
||||
} else {
|
||||
openBoostModal({ chatId });
|
||||
}
|
||||
closeMenu();
|
||||
});
|
||||
|
||||
@ -522,6 +529,14 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
{lang(isChannel ? 'ProfileJoinChannel' : 'ProfileJoinGroup')}
|
||||
</MenuItem>
|
||||
)}
|
||||
{canShowBoostModal && !canViewBoosts && (
|
||||
<MenuItem
|
||||
icon="boost-outline"
|
||||
onClick={handleBoostClick}
|
||||
>
|
||||
{lang(isChannel ? 'BoostingBoostChannelMenu' : 'BoostingBoostGroupMenu')}
|
||||
</MenuItem>
|
||||
)}
|
||||
{canAddContact && (
|
||||
<MenuItem
|
||||
icon="add-user"
|
||||
@ -589,7 +604,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
||||
)}
|
||||
{canViewBoosts && (
|
||||
<MenuItem
|
||||
icon="boost"
|
||||
icon="boost-outline"
|
||||
onClick={handleBoostClick}
|
||||
>
|
||||
{lang('Boosts')}
|
||||
|
||||
@ -763,10 +763,11 @@ export default memo(withGlobal<OwnProps>(
|
||||
const bot = selectBot(global, chatId);
|
||||
const pinnedIds = selectPinnedIds(global, chatId, threadId);
|
||||
const { chatId: audioChatId, messageId: audioMessageId } = audioPlayer;
|
||||
const chatFullInfo = chatId ? selectChatFullInfo(global, chatId) : undefined;
|
||||
|
||||
const threadInfo = selectThreadInfo(global, chatId, threadId);
|
||||
const isMessageThread = Boolean(!threadInfo?.isCommentsInfo && threadInfo?.fromChannelId);
|
||||
const canPost = chat && getCanPostInChat(chat, threadId, isMessageThread);
|
||||
const canPost = chat && getCanPostInChat(chat, threadId, isMessageThread, chatFullInfo);
|
||||
const isBotNotStarted = selectIsChatBotNotStarted(global, chatId);
|
||||
const isPinnedMessageList = messageListType === 'pinned';
|
||||
const isMainThread = messageListType === 'thread' && threadId === MAIN_THREAD_ID;
|
||||
@ -781,7 +782,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
const canStartBot = !canRestartBot && isBotNotStarted;
|
||||
const canUnblock = isUserBlocked && !bot;
|
||||
const shouldLoadFullChat = Boolean(
|
||||
chat && isChatGroup(chat) && !selectChatFullInfo(global, chat.id),
|
||||
chat && isChatGroup(chat) && !chatFullInfo,
|
||||
);
|
||||
const draftReplyInfo = selectDraft(global, chatId, threadId)?.replyInfo;
|
||||
const shouldBlockSendInForum = chat?.isForum
|
||||
|
||||
@ -11,7 +11,6 @@ import type { StickerSetOrReactionsSetOrRecent, ThreadId } from '../../../types'
|
||||
import {
|
||||
CHAT_STICKER_SET_ID,
|
||||
FAVORITE_SYMBOL_SET_ID,
|
||||
PREMIUM_STICKER_SET_ID,
|
||||
RECENT_SYMBOL_SET_ID,
|
||||
SLIDE_TRANSITION_DURATION,
|
||||
STICKER_PICKER_MAX_SHARED_COVERS,
|
||||
@ -23,7 +22,7 @@ import {
|
||||
} from '../../../global/selectors';
|
||||
import animateHorizontalScroll from '../../../util/animateHorizontalScroll';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
import { pickTruthy, uniqueByField } from '../../../util/iteratees';
|
||||
import { pickTruthy } from '../../../util/iteratees';
|
||||
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
||||
import { IS_TOUCH_ENV } from '../../../util/windowEnvironment';
|
||||
import { REM } from '../../common/helpers/mediaDimensions';
|
||||
@ -37,7 +36,6 @@ import { useStickerPickerObservers } from '../../common/hooks/useStickerPickerOb
|
||||
import useAsyncRendering from '../../right/hooks/useAsyncRendering';
|
||||
|
||||
import Avatar from '../../common/Avatar';
|
||||
import PremiumIcon from '../../common/PremiumIcon';
|
||||
import StickerButton from '../../common/StickerButton';
|
||||
import StickerSet from '../../common/StickerSet';
|
||||
import Button from '../../ui/Button';
|
||||
@ -65,7 +63,6 @@ type StateProps = {
|
||||
chat?: ApiChat;
|
||||
recentStickers: ApiSticker[];
|
||||
favoriteStickers: ApiSticker[];
|
||||
premiumStickers: ApiSticker[];
|
||||
stickerSetsById: Record<string, ApiStickerSet>;
|
||||
chatStickerSetId?: string;
|
||||
addedSetIds?: string[];
|
||||
@ -86,7 +83,6 @@ const StickerPicker: FC<OwnProps & StateProps> = ({
|
||||
canSendStickers,
|
||||
recentStickers,
|
||||
favoriteStickers,
|
||||
premiumStickers,
|
||||
addedSetIds,
|
||||
stickerSetsById,
|
||||
chatStickerSetId,
|
||||
@ -140,8 +136,6 @@ const StickerPicker: FC<OwnProps & StateProps> = ({
|
||||
|
||||
const defaultSets = [];
|
||||
|
||||
const existingAddedSetIds = Object.values(pickTruthy(stickerSetsById, addedSetIds));
|
||||
|
||||
if (favoriteStickers.length) {
|
||||
defaultSets.push({
|
||||
id: FAVORITE_SYMBOL_SET_ID,
|
||||
@ -162,46 +156,18 @@ const StickerPicker: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
}
|
||||
|
||||
if (isCurrentUserPremium) {
|
||||
const addedPremiumStickers = existingAddedSetIds
|
||||
.map(({ stickers }) => stickers?.filter((sticker) => sticker.hasEffect))
|
||||
.flat()
|
||||
.filter(Boolean);
|
||||
|
||||
const totalPremiumStickers = uniqueByField([...addedPremiumStickers, ...premiumStickers], 'id');
|
||||
|
||||
if (totalPremiumStickers.length) {
|
||||
defaultSets.push({
|
||||
id: PREMIUM_STICKER_SET_ID,
|
||||
accessHash: '0',
|
||||
title: lang('PremiumStickers'),
|
||||
stickers: totalPremiumStickers,
|
||||
count: totalPremiumStickers.length,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const userSetIds = [...(addedSetIds || [])];
|
||||
if (chatStickerSetId) {
|
||||
const fullSet = stickerSetsById[chatStickerSetId];
|
||||
if (fullSet) {
|
||||
defaultSets.push({
|
||||
id: CHAT_STICKER_SET_ID,
|
||||
accessHash: fullSet.accessHash,
|
||||
title: lang('GroupStickers'),
|
||||
stickers: fullSet.stickers,
|
||||
count: fullSet.stickers!.length,
|
||||
});
|
||||
}
|
||||
userSetIds.unshift(chatStickerSetId);
|
||||
}
|
||||
|
||||
const existingAddedSetIds = Object.values(pickTruthy(stickerSetsById, userSetIds));
|
||||
|
||||
return [
|
||||
...defaultSets,
|
||||
...existingAddedSetIds,
|
||||
];
|
||||
}, [
|
||||
addedSetIds, stickerSetsById, favoriteStickers, recentStickers, isCurrentUserPremium, chatStickerSetId, lang,
|
||||
premiumStickers,
|
||||
]);
|
||||
}, [addedSetIds, stickerSetsById, favoriteStickers, recentStickers, chatStickerSetId, lang]);
|
||||
|
||||
const noPopulatedSets = useMemo(() => (
|
||||
areAddedLoaded
|
||||
@ -266,7 +232,6 @@ const StickerPicker: FC<OwnProps & StateProps> = ({
|
||||
if (stickerSet.id === RECENT_SYMBOL_SET_ID
|
||||
|| stickerSet.id === FAVORITE_SYMBOL_SET_ID
|
||||
|| stickerSet.id === CHAT_STICKER_SET_ID
|
||||
|| stickerSet.id === PREMIUM_STICKER_SET_ID
|
||||
|| stickerSet.hasThumbnail
|
||||
|| !firstSticker
|
||||
) {
|
||||
@ -281,9 +246,7 @@ const StickerPicker: FC<OwnProps & StateProps> = ({
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => selectStickerSet(index)}
|
||||
>
|
||||
{stickerSet.id === PREMIUM_STICKER_SET_ID ? (
|
||||
<PremiumIcon withGradient big />
|
||||
) : stickerSet.id === RECENT_SYMBOL_SET_ID ? (
|
||||
{stickerSet.id === RECENT_SYMBOL_SET_ID ? (
|
||||
<i className="icon icon-recent" />
|
||||
) : stickerSet.id === FAVORITE_SYMBOL_SET_ID ? (
|
||||
<i className="icon icon-favorite" />
|
||||
@ -374,6 +337,7 @@ const StickerPicker: FC<OwnProps & StateProps> = ({
|
||||
isSavedMessages={isSavedMessages}
|
||||
isCurrentUserPremium={isCurrentUserPremium}
|
||||
isTranslucent={isTranslucent}
|
||||
isChatStickerSet={stickerSet.id === chatStickerSetId}
|
||||
onStickerSelect={handleStickerSelect}
|
||||
onStickerUnfave={handleStickerUnfave}
|
||||
onStickerFave={handleStickerFave}
|
||||
@ -393,7 +357,6 @@ export default memo(withGlobal<OwnProps>(
|
||||
added,
|
||||
recent,
|
||||
favorite,
|
||||
premiumSet,
|
||||
} = global.stickers;
|
||||
|
||||
const isSavedMessages = selectIsChatWithSelf(global, chatId);
|
||||
@ -404,7 +367,6 @@ export default memo(withGlobal<OwnProps>(
|
||||
chat,
|
||||
recentStickers: recent.stickers,
|
||||
favoriteStickers: favorite.stickers,
|
||||
premiumStickers: premiumSet.stickers,
|
||||
stickerSetsById: setsById,
|
||||
addedSetIds: added.setIds,
|
||||
canAnimate: selectShouldLoopStickers(global),
|
||||
|
||||
@ -222,6 +222,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-chat {
|
||||
background-color: var(--color-text-secondary);
|
||||
color: var(--color-background);
|
||||
border-radius: 0.5rem;
|
||||
padding-inline: 0.25rem;
|
||||
margin-inline-start: 0.5rem;
|
||||
}
|
||||
|
||||
&-locked-icon {
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
|
||||
@ -81,6 +81,7 @@ import {
|
||||
selectIsMessageSelected,
|
||||
selectMessageIdsByGroupId,
|
||||
selectOutgoingStatus,
|
||||
selectPeer,
|
||||
selectPeerStory,
|
||||
selectPerformanceSettingsValue,
|
||||
selectReplySender,
|
||||
@ -222,7 +223,7 @@ type StateProps = {
|
||||
replyMessageChat?: ApiChat;
|
||||
isReplyPrivate?: boolean;
|
||||
replyStory?: ApiTypeStory;
|
||||
storySender?: ApiUser;
|
||||
storySender?: ApiPeer;
|
||||
outgoingStatus?: ApiMessageOutgoingStatus;
|
||||
uploadProgress?: number;
|
||||
isInDocumentGroup: boolean;
|
||||
@ -279,7 +280,9 @@ type StateProps = {
|
||||
isConnected: boolean;
|
||||
isLoadingComments?: boolean;
|
||||
shouldWarnAboutSvg?: boolean;
|
||||
senderBoosts?: number;
|
||||
tags?: Record<ApiReactionKey, ApiSavedReactionTag>;
|
||||
canTranscribeVoice?: boolean;
|
||||
};
|
||||
|
||||
type MetaPosition =
|
||||
@ -394,7 +397,9 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
isConnected,
|
||||
getIsMessageListReady,
|
||||
shouldWarnAboutSvg,
|
||||
senderBoosts,
|
||||
tags,
|
||||
canTranscribeVoice,
|
||||
onPinnedIntersectionChange,
|
||||
}) => {
|
||||
const {
|
||||
@ -655,7 +660,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
} = getMessageContent(message);
|
||||
|
||||
const { replyToMsgId, replyToPeerId, isQuote } = messageReplyInfo || {};
|
||||
const { userId: storyReplyUserId, storyId: storyReplyId } = storyReplyInfo || {};
|
||||
const { peerId: storyReplyPeerId, storyId: storyReplyId } = storyReplyInfo || {};
|
||||
|
||||
const detectedLanguage = useTextLanguage(
|
||||
text?.text,
|
||||
@ -739,7 +744,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
);
|
||||
|
||||
useEnsureStory(
|
||||
storyReplyUserId || chatId,
|
||||
storyReplyPeerId || chatId,
|
||||
storyReplyId,
|
||||
replyStory,
|
||||
);
|
||||
@ -1132,7 +1137,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
isTranscriptionError={isTranscriptionError}
|
||||
canDownload={!isProtected}
|
||||
onHideTranscription={setTranscriptionHidden}
|
||||
canTranscribe={isPremium && !hasTtl}
|
||||
canTranscribe={canTranscribeVoice && !hasTtl}
|
||||
/>
|
||||
)}
|
||||
{document && (
|
||||
@ -1312,6 +1317,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
<div className="title-spacer" />
|
||||
{forwardInfo?.isLinkedChannelPost ? (
|
||||
<span className="admin-title" dir="auto">{lang('DiscussChannel')}</span>
|
||||
) : message.forwardInfo?.postAuthorTitle && isGroup && asForwarded ? (
|
||||
@ -1325,6 +1331,12 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
)}
|
||||
</span>
|
||||
) : undefined}
|
||||
{Boolean(senderBoosts) && (
|
||||
<span className="sender-boosts" aria-hidden>
|
||||
<Icon name={senderBoosts > 1 ? 'boosts' : 'boost'} />
|
||||
{senderBoosts > 1 ? senderBoosts : undefined}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -1499,7 +1511,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
const isThreadTop = message.id === threadId;
|
||||
|
||||
const { replyToMsgId, replyToPeerId, replyFrom } = getMessageReplyInfo(message) || {};
|
||||
const { userId: storyReplyUserId, storyId: storyReplyId } = getStoryReplyInfo(message) || {};
|
||||
const { peerId: storyReplyPeerId, storyId: storyReplyId } = getStoryReplyInfo(message) || {};
|
||||
|
||||
const shouldHideReply = replyToMsgId && replyToMsgId === threadId;
|
||||
const replyMessage = replyToMsgId ? selectChatMessage(global, replyToPeerId || chatId, replyToMsgId) : undefined;
|
||||
@ -1512,10 +1524,10 @@ export default memo(withGlobal<OwnProps>(
|
||||
const isReplyPrivate = !isRepliesChat && !isAnonymousForwards && replyMessageChat && !isChatPublic(replyMessageChat)
|
||||
&& (replyMessageChat.isNotJoined || replyMessageChat.isRestricted);
|
||||
const isReplyToTopicStart = replyMessage?.content.action?.type === 'topicCreate';
|
||||
const replyStory = storyReplyId && storyReplyUserId
|
||||
? selectPeerStory(global, storyReplyUserId, storyReplyId)
|
||||
const replyStory = storyReplyId && storyReplyPeerId
|
||||
? selectPeerStory(global, storyReplyPeerId, storyReplyId)
|
||||
: undefined;
|
||||
const storySender = storyReplyUserId ? selectUser(global, storyReplyUserId) : undefined;
|
||||
const storySender = storyReplyPeerId ? selectPeer(global, storyReplyPeerId) : undefined;
|
||||
|
||||
const uploadProgress = selectUploadProgress(global, message);
|
||||
const isFocused = messageListType === 'thread' && (
|
||||
@ -1572,6 +1584,14 @@ export default memo(withGlobal<OwnProps>(
|
||||
|
||||
const hasActiveReactions = Boolean(reactionMessage && activeReactions[getMessageKey(reactionMessage)]?.length);
|
||||
|
||||
const isPremium = selectIsCurrentUserPremium(global);
|
||||
const senderBoosts = sender && selectIsChatWithSelf(global, sender.id)
|
||||
? (chatFullInfo?.boostsApplied ?? message.senderBoosts) : message.senderBoosts;
|
||||
|
||||
const chatLevel = chat?.boostLevel || 0;
|
||||
const transcribeMinLevel = global.appConfig?.groupTranscribeLevelMin;
|
||||
const canTranscribeVoice = isPremium || Boolean(transcribeMinLevel && chatLevel >= transcribeMinLevel);
|
||||
|
||||
return {
|
||||
theme: selectTheme(global),
|
||||
forceSenderName,
|
||||
@ -1627,7 +1647,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
hasUnreadReaction,
|
||||
isTranscribing: transcriptionId !== undefined && global.transcriptions[transcriptionId]?.isPending,
|
||||
transcribedText: transcriptionId !== undefined ? global.transcriptions[transcriptionId]?.text : undefined,
|
||||
isPremium: selectIsCurrentUserPremium(global),
|
||||
isPremium,
|
||||
senderAdminMember,
|
||||
messageTopic,
|
||||
hasTopicChip,
|
||||
@ -1652,7 +1672,9 @@ export default memo(withGlobal<OwnProps>(
|
||||
isResizingContainer,
|
||||
focusedQuote,
|
||||
}),
|
||||
senderBoosts,
|
||||
tags: global.savedReactionTags?.byKey,
|
||||
canTranscribeVoice,
|
||||
};
|
||||
},
|
||||
)(Message));
|
||||
|
||||
@ -325,19 +325,32 @@
|
||||
margin-left: 0.25rem;
|
||||
}
|
||||
|
||||
.title-spacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.admin-title {
|
||||
flex: 1;
|
||||
margin-left: 1rem;
|
||||
text-align: right;
|
||||
font-weight: 400;
|
||||
font-size: 0.75rem;
|
||||
margin-top: -0.125rem;
|
||||
color: rgba(var(--color-text-meta-rgb), 0.75);
|
||||
user-select: none;
|
||||
|
||||
.Message.own & {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
}
|
||||
|
||||
.sender-boosts {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.75rem;
|
||||
margin-top: -0.125rem;
|
||||
margin-inline-start: 0.125rem;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
.message-subheader {
|
||||
|
||||
@ -27,6 +27,7 @@ export function getWebpageButtonText(type?: string) {
|
||||
case 'telegram_story':
|
||||
return 'lng_view_button_story';
|
||||
case 'telegram_channel_boost':
|
||||
case 'telegram_group_boost':
|
||||
return 'lng_view_button_boost';
|
||||
default:
|
||||
return undefined;
|
||||
|
||||
@ -27,6 +27,12 @@
|
||||
.description {
|
||||
padding: 0.5rem;
|
||||
line-height: 1.25;
|
||||
text-align: center;
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.chip {
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
import React, { memo, useMemo } from '../../../lib/teact/teact';
|
||||
import React, { memo, useEffect, useMemo } from '../../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../../global';
|
||||
|
||||
import type { ApiChat, ApiMyBoost } from '../../../api/types';
|
||||
import type { ApiChat, ApiChatFullInfo, ApiMyBoost } from '../../../api/types';
|
||||
import type { TabState } from '../../../global/types';
|
||||
|
||||
import { getChatTitle } from '../../../global/helpers';
|
||||
import { selectChat, selectIsCurrentUserPremium } from '../../../global/selectors';
|
||||
import { getChatTitle, isChatAdmin, isChatChannel } from '../../../global/helpers';
|
||||
import { selectChat, selectChatFullInfo, selectIsCurrentUserPremium } from '../../../global/selectors';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
import { formatDateInFuture } from '../../../util/dateFormat';
|
||||
import { getServerTime } from '../../../util/serverTime';
|
||||
import { getBoostProgressInfo } from '../../common/helpers/boostInfo';
|
||||
@ -50,14 +51,16 @@ export type OwnProps = {
|
||||
|
||||
type StateProps = {
|
||||
chat?: ApiChat;
|
||||
boostedChat?: ApiChat;
|
||||
chatFullInfo?: ApiChatFullInfo;
|
||||
prevBoostedChat?: ApiChat;
|
||||
isCurrentUserPremium?: boolean;
|
||||
};
|
||||
|
||||
const BoostModal = ({
|
||||
info,
|
||||
chat,
|
||||
boostedChat,
|
||||
chatFullInfo,
|
||||
prevBoostedChat,
|
||||
isCurrentUserPremium,
|
||||
}: OwnProps & StateProps) => {
|
||||
const {
|
||||
@ -65,16 +68,25 @@ const BoostModal = ({
|
||||
closeBoostModal,
|
||||
requestConfetti,
|
||||
openPremiumModal,
|
||||
loadFullChat,
|
||||
} = getActions();
|
||||
|
||||
const [isReplaceModalOpen, openReplaceModal, closeReplaceModal] = useFlag();
|
||||
const [isWaitDialogOpen, openWaitDialog, closeWaitDialog] = useFlag();
|
||||
const [isPremiumDialogOpen, openPremiumDialog, closePremiumDialog] = useFlag();
|
||||
|
||||
const isChannel = chat && isChatChannel(chat);
|
||||
|
||||
const isOpen = Boolean(info);
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
useEffect(() => {
|
||||
if (chat && !chatFullInfo) {
|
||||
loadFullChat({ chatId: chat.id });
|
||||
}
|
||||
}, [chat, chatFullInfo]);
|
||||
|
||||
const chatTitle = useMemo(() => {
|
||||
if (!chat) {
|
||||
return undefined;
|
||||
@ -84,12 +96,12 @@ const BoostModal = ({
|
||||
}, [chat, lang]);
|
||||
|
||||
const boostedChatTitle = useMemo(() => {
|
||||
if (!boostedChat) {
|
||||
if (!prevBoostedChat) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return getChatTitle(lang, boostedChat);
|
||||
}, [boostedChat, lang]);
|
||||
return getChatTitle(lang, prevBoostedChat);
|
||||
}, [prevBoostedChat, lang]);
|
||||
|
||||
const {
|
||||
isStatusLoaded,
|
||||
@ -111,7 +123,7 @@ const BoostModal = ({
|
||||
}
|
||||
|
||||
const {
|
||||
level, currentLevelBoosts, hasMyBoost,
|
||||
hasMyBoost,
|
||||
} = info.boostStatus;
|
||||
|
||||
const firstBoost = info?.myBoosts && getFirstAvailableBoost(info.myBoosts, chat.id);
|
||||
@ -123,36 +135,28 @@ const BoostModal = ({
|
||||
hasNextLevel,
|
||||
levelProgress,
|
||||
remainingBoosts,
|
||||
isMaxLevel,
|
||||
} = getBoostProgressInfo(info.boostStatus, true);
|
||||
|
||||
const hasBoost = hasMyBoost;
|
||||
const isJustUpgraded = boosts === currentLevelBoosts && hasBoost;
|
||||
|
||||
const left = lang('BoostsLevel', currentLevel);
|
||||
const right = hasNextLevel ? lang('BoostsLevel', currentLevel + 1) : undefined;
|
||||
|
||||
const moreBoosts = lang('ChannelBoost.MoreBoosts', remainingBoosts);
|
||||
const currentStoriesPerDay = lang('ChannelBoost.StoriesPerDay', level);
|
||||
const nextLevelStoriesPerDay = lang('ChannelBoost.StoriesPerDay', level + 1);
|
||||
|
||||
const modalTitle = hasBoost ? lang('YouBoostedChannel2', chatTitle)
|
||||
: level === 0 ? lang('lng_boost_channel_title_first') : lang('lng_boost_channel_title_more');
|
||||
const modalTitle = isChannel ? lang('BoostChannel') : lang('BoostGroup');
|
||||
|
||||
const boostsLeftToUnrestrict = (chatFullInfo?.boostsToUnrestrict || 0) - (chatFullInfo?.boostsApplied || 0);
|
||||
|
||||
let description: string | undefined;
|
||||
if (level === 0) {
|
||||
if (!hasBoost) {
|
||||
description = lang('ChannelBoost.EnableStoriesForChannelText', [chatTitle, moreBoosts]);
|
||||
} else {
|
||||
description = lang('ChannelBoost.EnableStoriesMoreRequired', moreBoosts);
|
||||
}
|
||||
} else if (isJustUpgraded) {
|
||||
if (level === 1) {
|
||||
description = lang('ChannelBoost.EnabledStoriesForChannelText');
|
||||
} else {
|
||||
description = lang('ChannelBoost.BoostedChannelReachedLevel', [level, currentStoriesPerDay]);
|
||||
}
|
||||
if (isMaxLevel) {
|
||||
description = lang('BoostsMaxLevelReached');
|
||||
} else if (boostsLeftToUnrestrict > 0 && !isChatAdmin(chat)) {
|
||||
const boostTimes = lang('GroupBoost.BoostToUnrestrict.Times', boostsLeftToUnrestrict);
|
||||
description = lang('GroupBoost.BoostToUnrestrict', [boostTimes, chatTitle]);
|
||||
} else {
|
||||
description = lang('ChannelBoost.HelpUpgradeChannelText', [chatTitle, moreBoosts, nextLevelStoriesPerDay]);
|
||||
description = lang('ChannelBoost.MoreBoostsNeeded.Text', [chatTitle, moreBoosts]);
|
||||
}
|
||||
|
||||
return {
|
||||
@ -166,9 +170,9 @@ const BoostModal = ({
|
||||
descriptionText: description,
|
||||
boost: firstBoost,
|
||||
isBoosted: hasBoost,
|
||||
canBoostMore: areBoostsInDifferentChannels,
|
||||
canBoostMore: areBoostsInDifferentChannels && !isMaxLevel,
|
||||
};
|
||||
}, [chat, chatTitle, info, lang]);
|
||||
}, [chat, chatTitle, info, lang, chatFullInfo, isChannel]);
|
||||
|
||||
const isBoostDisabled = !info?.myBoosts?.length && isCurrentUserPremium;
|
||||
const isReplacingBoost = boost?.chatId && boost.chatId !== info?.chatId;
|
||||
@ -189,6 +193,7 @@ const BoostModal = ({
|
||||
if (!boost) {
|
||||
if (!isCurrentUserPremium) {
|
||||
openPremiumDialog();
|
||||
return;
|
||||
}
|
||||
|
||||
closeBoostModal();
|
||||
@ -231,6 +236,11 @@ const BoostModal = ({
|
||||
floatingBadgeText={value}
|
||||
floatingBadgeIcon="boost"
|
||||
/>
|
||||
{isBoosted && (
|
||||
<div className={buildClassName(styles.description, styles.bold)}>
|
||||
{lang('ChannelBoost.YouBoostedChannelText', chatTitle)}
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.description}>
|
||||
{renderText(descriptionText, ['simple_markdown', 'emoji'])}
|
||||
</div>
|
||||
@ -239,7 +249,7 @@ const BoostModal = ({
|
||||
{canBoostMore ? (
|
||||
<>
|
||||
<Icon name="boost" />
|
||||
{lang(isBoosted && canBoostMore ? 'BoostingBoostAgain' : 'ChannelBoost.BoostChannel')}
|
||||
{lang(isChannel ? 'ChannelBoost.BoostChannel' : 'GroupBoost.BoostGroup')}
|
||||
</>
|
||||
) : lang('OK')}
|
||||
</Button>
|
||||
@ -269,7 +279,7 @@ const BoostModal = ({
|
||||
>
|
||||
<div className={styles.avatarContainer}>
|
||||
<div className={styles.boostedWrapper}>
|
||||
<Avatar peer={boostedChat} size="large" />
|
||||
<Avatar peer={prevBoostedChat} size="large" />
|
||||
<Icon name="boostcircle" className={styles.boostedMark} />
|
||||
</div>
|
||||
<Icon name="next" className={styles.arrow} />
|
||||
@ -334,12 +344,14 @@ function areAllBoostsInChannel(myBoosts: ApiMyBoost[], chatId: string) {
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
(global, { info }): StateProps => {
|
||||
const chat = info && selectChat(global, info?.chatId);
|
||||
const chatFullInfo = chat && selectChatFullInfo(global, chat.id);
|
||||
const firstBoost = info?.myBoosts && getFirstAvailableBoost(info.myBoosts, info.chatId);
|
||||
const boostedChat = firstBoost?.chatId ? selectChat(global, firstBoost?.chatId) : undefined;
|
||||
|
||||
return {
|
||||
chat,
|
||||
boostedChat,
|
||||
chatFullInfo,
|
||||
prevBoostedChat: boostedChat,
|
||||
isCurrentUserPremium: selectIsCurrentUserPremium(global),
|
||||
};
|
||||
},
|
||||
|
||||
@ -2,13 +2,14 @@ import type { FC } from '../../lib/teact/teact';
|
||||
import React, { memo, useCallback, useRef } from '../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../global';
|
||||
|
||||
import type { ApiChat, ApiVideo } from '../../api/types';
|
||||
import type { ApiChat, ApiChatFullInfo, ApiVideo } from '../../api/types';
|
||||
import type { MessageList } from '../../global/types';
|
||||
|
||||
import { getAllowedAttachmentOptions, getCanPostInChat } from '../../global/helpers';
|
||||
import {
|
||||
selectCanScheduleUntilOnline,
|
||||
selectChat,
|
||||
selectChatFullInfo,
|
||||
selectCurrentGifSearch,
|
||||
selectCurrentMessageList,
|
||||
selectIsChatWithBot,
|
||||
@ -37,6 +38,7 @@ type StateProps = {
|
||||
query?: string;
|
||||
results?: ApiVideo[];
|
||||
chat?: ApiChat;
|
||||
chatFullInfo?: ApiChatFullInfo;
|
||||
isChatWithBot?: boolean;
|
||||
canScheduleUntilOnline?: boolean;
|
||||
isSavedMessages?: boolean;
|
||||
@ -52,6 +54,7 @@ const GifSearch: FC<OwnProps & StateProps> = ({
|
||||
query,
|
||||
results,
|
||||
chat,
|
||||
chatFullInfo,
|
||||
isChatWithBot,
|
||||
canScheduleUntilOnline,
|
||||
isSavedMessages,
|
||||
@ -74,7 +77,7 @@ const GifSearch: FC<OwnProps & StateProps> = ({
|
||||
observe: observeIntersection,
|
||||
} = useIntersectionObserver({ rootRef: containerRef, debounceMs: INTERSECTION_DEBOUNCE });
|
||||
|
||||
const canSendGifs = canPostInChat && getAllowedAttachmentOptions(chat, isChatWithBot).canSendGifs;
|
||||
const canSendGifs = canPostInChat && getAllowedAttachmentOptions(chat, chatFullInfo, isChatWithBot).canSendGifs;
|
||||
|
||||
const handleGifClick = useCallback((gif: ApiVideo, isSilent?: boolean, shouldSchedule?: boolean) => {
|
||||
if (canSendGifs) {
|
||||
@ -166,11 +169,13 @@ export default memo(withGlobal(
|
||||
const { query, results } = currentSearch || {};
|
||||
const { chatId, threadId } = selectCurrentMessageList(global) || {};
|
||||
const chat = chatId ? selectChat(global, chatId) : undefined;
|
||||
const chatFullInfo = chatId ? selectChatFullInfo(global, chatId) : undefined;
|
||||
const isChatWithBot = chat ? selectIsChatWithBot(global, chat) : undefined;
|
||||
const isSavedMessages = Boolean(chatId) && selectIsChatWithSelf(global, chatId);
|
||||
const threadInfo = chatId && threadId ? selectThreadInfo(global, chatId, threadId) : undefined;
|
||||
const isMessageThread = Boolean(!threadInfo?.isCommentsInfo && threadInfo?.fromChannelId);
|
||||
const canPostInChat = Boolean(chat) && Boolean(threadId) && getCanPostInChat(chat, threadId, isMessageThread);
|
||||
const canPostInChat = Boolean(chat) && Boolean(threadId)
|
||||
&& getCanPostInChat(chat, threadId, isMessageThread, chatFullInfo);
|
||||
|
||||
return {
|
||||
query,
|
||||
|
||||
@ -260,42 +260,36 @@ const ManageGroupAdminRights: FC<OwnProps & StateProps> = ({
|
||||
onChange={handlePermissionChange}
|
||||
/>
|
||||
</div>
|
||||
{isChannel && (
|
||||
<div className="ListItem">
|
||||
<Checkbox
|
||||
name="postStories"
|
||||
checked={Boolean(permissions.postStories)}
|
||||
label={lang('EditAdminPostStories')}
|
||||
blocking
|
||||
disabled={getControlIsDisabled('postStories')}
|
||||
onChange={handlePermissionChange}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{isChannel && (
|
||||
<div className="ListItem">
|
||||
<Checkbox
|
||||
name="editStories"
|
||||
checked={Boolean(permissions.editStories)}
|
||||
label={lang('EditAdminEditStories')}
|
||||
blocking
|
||||
disabled={getControlIsDisabled('editStories')}
|
||||
onChange={handlePermissionChange}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{isChannel && (
|
||||
<div className="ListItem">
|
||||
<Checkbox
|
||||
name="deleteStories"
|
||||
checked={Boolean(permissions.deleteStories)}
|
||||
label={lang('EditAdminDeleteStories')}
|
||||
blocking
|
||||
disabled={getControlIsDisabled('deleteStories')}
|
||||
onChange={handlePermissionChange}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="ListItem">
|
||||
<Checkbox
|
||||
name="postStories"
|
||||
checked={Boolean(permissions.postStories)}
|
||||
label={lang('EditAdminPostStories')}
|
||||
blocking
|
||||
disabled={getControlIsDisabled('postStories')}
|
||||
onChange={handlePermissionChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="ListItem">
|
||||
<Checkbox
|
||||
name="editStories"
|
||||
checked={Boolean(permissions.editStories)}
|
||||
label={lang('EditAdminEditStories')}
|
||||
blocking
|
||||
disabled={getControlIsDisabled('editStories')}
|
||||
onChange={handlePermissionChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="ListItem">
|
||||
<Checkbox
|
||||
name="deleteStories"
|
||||
checked={Boolean(permissions.deleteStories)}
|
||||
label={lang('EditAdminDeleteStories')}
|
||||
blocking
|
||||
disabled={getControlIsDisabled('deleteStories')}
|
||||
onChange={handlePermissionChange}
|
||||
/>
|
||||
</div>
|
||||
{!isChannel && (
|
||||
<div className="ListItem">
|
||||
<Checkbox
|
||||
|
||||
@ -5,6 +5,7 @@ import React, {
|
||||
import { getActions, withGlobal } from '../../global';
|
||||
|
||||
import type {
|
||||
ApiChat,
|
||||
ApiMediaAreaChannelPost,
|
||||
ApiPeer, ApiStealthMode, ApiStory, ApiTypeStory,
|
||||
} from '../../api/types';
|
||||
@ -13,7 +14,7 @@ import type { Signal } from '../../util/signals';
|
||||
import { MAIN_THREAD_ID } from '../../api/types';
|
||||
|
||||
import { EDITABLE_STORY_INPUT_CSS_SELECTOR, EDITABLE_STORY_INPUT_ID } from '../../config';
|
||||
import { getSenderTitle, isUserId } from '../../global/helpers';
|
||||
import { getSenderTitle, isChatChannel, isUserId } from '../../global/helpers';
|
||||
import {
|
||||
selectChat,
|
||||
selectIsCurrentUserPremium,
|
||||
@ -86,6 +87,7 @@ interface OwnProps {
|
||||
interface StateProps {
|
||||
peer: ApiPeer;
|
||||
forwardSender?: ApiPeer;
|
||||
fromPeer?: ApiPeer;
|
||||
story?: ApiTypeStory;
|
||||
isMuted: boolean;
|
||||
orderedIds?: number[];
|
||||
@ -109,6 +111,7 @@ function Story({
|
||||
storyId,
|
||||
peer,
|
||||
forwardSender,
|
||||
fromPeer,
|
||||
isMuted,
|
||||
isArchivedStories,
|
||||
isPrivateStories,
|
||||
@ -124,10 +127,10 @@ function Story({
|
||||
getIsAnimating,
|
||||
isCurrentUserPremium,
|
||||
stealthMode,
|
||||
withHeaderAnimation,
|
||||
onDelete,
|
||||
onClose,
|
||||
onReport,
|
||||
withHeaderAnimation,
|
||||
}: OwnProps & StateProps) {
|
||||
const {
|
||||
viewStory,
|
||||
@ -179,7 +182,9 @@ function Story({
|
||||
|
||||
const isLoadedStory = story && 'content' in story;
|
||||
const isChangelog = peerId === storyChangelogUserId;
|
||||
const isChannel = !isUserId(peerId);
|
||||
const isUserStory = isUserId(peerId);
|
||||
const isChatStory = !isUserStory;
|
||||
const isChannelStory = isChatStory && isChatChannel(peer as ApiChat);
|
||||
const isOut = isLoadedStory && story.isOut;
|
||||
|
||||
const canPinToProfile = useCurrentOrPrev(
|
||||
@ -221,7 +226,8 @@ function Story({
|
||||
? story.content.video.duration
|
||||
: undefined;
|
||||
|
||||
const shouldShowFooter = isLoadedStory && (isOut || isChannel);
|
||||
const shouldShowComposer = !(isOut && isUserStory) && !isChangelog && !isChannelStory;
|
||||
const shouldShowFooter = isLoadedStory && !shouldShowComposer && (isOut || isChannelStory);
|
||||
const headerAnimation = isMobile && withHeaderAnimation ? 'slideFade' : 'none';
|
||||
|
||||
const {
|
||||
@ -239,7 +245,7 @@ function Story({
|
||||
const {
|
||||
shouldRender: shouldRenderComposer,
|
||||
transitionClassNames: composerAppearanceAnimationClassNames,
|
||||
} = useShowTransition(!isOut && !isChangelog && !isChannel);
|
||||
} = useShowTransition(shouldShowComposer);
|
||||
|
||||
const {
|
||||
shouldRender: shouldRenderCaptionBackdrop,
|
||||
@ -340,11 +346,11 @@ function Story({
|
||||
}, [hasAllData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOut || isDeletedStory || areViewsExpired) return;
|
||||
if (!isLoadedStory || isDeletedStory || areViewsExpired) return;
|
||||
|
||||
// Refresh recent viewers list each time
|
||||
loadStoryViews({ peerId, storyId, isPreload: true });
|
||||
}, [isDeletedStory, areViewsExpired, isOut, peerId, storyId]);
|
||||
// Refresh counters each time
|
||||
loadStoryViews({ peerId, storyId });
|
||||
}, [isDeletedStory, areViewsExpired, isLoadedStory, peerId, storyId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
@ -415,6 +421,11 @@ function Story({
|
||||
openChat({ id: forwardSender!.id });
|
||||
});
|
||||
|
||||
const handleFromPeerClick = useLastCallback(() => {
|
||||
onClose();
|
||||
openChat({ id: fromPeer!.id });
|
||||
});
|
||||
|
||||
const handleOpenPrevStory = useLastCallback(() => {
|
||||
openPreviousStory();
|
||||
});
|
||||
@ -569,7 +580,7 @@ function Story({
|
||||
}
|
||||
|
||||
function renderStoryPrivacyButton() {
|
||||
if (isChannel) return undefined;
|
||||
if (!isUserStory) return undefined;
|
||||
|
||||
let privacyIcon = 'channel-filled';
|
||||
const gradient: Record<string, [string, string]> = {
|
||||
@ -638,11 +649,24 @@ function Story({
|
||||
onClick={forwardSender ? handleForwardPeerClick : undefined}
|
||||
>
|
||||
<Icon name="loop" />
|
||||
<span className={styles.forwardHeaderText}>
|
||||
<span className={styles.headerTitle}>
|
||||
{renderText(forwardSenderTitle)}
|
||||
</span>
|
||||
</span>
|
||||
)}
|
||||
{fromPeer && (
|
||||
<span
|
||||
className={buildClassName(
|
||||
styles.storyMeta, styles.fromPeer,
|
||||
)}
|
||||
onClick={handleFromPeerClick}
|
||||
>
|
||||
<Avatar peer={fromPeer} size="micro" />
|
||||
<span className={styles.headerTitle}>
|
||||
{renderText(getSenderTitle(lang, fromPeer) || '')}
|
||||
</span>
|
||||
</span>
|
||||
)}
|
||||
{story && 'date' in story && (
|
||||
<span className={styles.storyMeta}>{formatRelativeTime(lang, serverTime, story.date)}</span>
|
||||
)}
|
||||
@ -693,17 +717,25 @@ function Story({
|
||||
>
|
||||
{canCopyLink && <MenuItem icon="copy" onClick={handleCopyStoryLink}>{lang('CopyLink')}</MenuItem>}
|
||||
{canPinToProfile && (
|
||||
<MenuItem icon="save-story" onClick={handlePinClick}>{lang('StorySave')}</MenuItem>
|
||||
<MenuItem icon="save-story" onClick={handlePinClick}>
|
||||
{lang(isUserStory ? 'StorySave' : 'SaveToPosts')}
|
||||
</MenuItem>
|
||||
)}
|
||||
{canUnpinFromProfile && (
|
||||
<MenuItem icon="delete" onClick={handleUnpinClick}>{lang('ArchiveStory')}</MenuItem>
|
||||
<MenuItem icon="delete" onClick={handleUnpinClick}>
|
||||
{lang(isUserStory ? 'ArchiveStory' : 'RemoveFromPosts')}
|
||||
</MenuItem>
|
||||
)}
|
||||
{canDownload && (
|
||||
<MenuItem icon="download" disabled={!downloadMediaData} onClick={handleDownload}>
|
||||
{lang('lng_media_download')}
|
||||
</MenuItem>
|
||||
)}
|
||||
<MenuItem icon="eye-closed-outline" onClick={handleOpenStealthModal}>{lang('StealthMode')}</MenuItem>
|
||||
{!isOut && isUserStory && (
|
||||
<MenuItem icon="eye-closed-outline" onClick={handleOpenStealthModal}>
|
||||
{lang('StealthMode')}
|
||||
</MenuItem>
|
||||
)}
|
||||
{!isOut && <MenuItem icon="flag" onClick={handleReportStoryClick}>{lang('lng_report_story')}</MenuItem>}
|
||||
{isOut && <MenuItem icon="delete" destructive onClick={handleDeleteStoryClick}>{lang('Delete')}</MenuItem>}
|
||||
</DropdownMenu>
|
||||
@ -818,7 +850,7 @@ function Story({
|
||||
</div>
|
||||
|
||||
{shouldShowFooter && (
|
||||
<StoryFooter story={story} className={appearanceAnimationClassNames} areViewsExpired={areViewsExpired} />
|
||||
<StoryFooter story={story} className={appearanceAnimationClassNames} />
|
||||
)}
|
||||
{shouldRenderCaptionBackdrop && (
|
||||
<div
|
||||
@ -853,7 +885,7 @@ function Story({
|
||||
editableInputId={EDITABLE_STORY_INPUT_ID}
|
||||
inputId="story-input-text"
|
||||
className={buildClassName(styles.composer, composerAppearanceAnimationClassNames)}
|
||||
inputPlaceholder={lang('ReplyPrivately')}
|
||||
inputPlaceholder={lang(isChatStory ? 'ReplyToGroupStory' : 'ReplyPrivately')}
|
||||
onForward={canShare ? handleForwardClick : undefined}
|
||||
onFocus={markComposerHasFocus}
|
||||
onBlur={unmarkComposerHasFocus}
|
||||
@ -888,21 +920,25 @@ export default memo(withGlobal<OwnProps>((global, {
|
||||
} = tabState;
|
||||
const { isOpen: isPremiumModalOpen } = premiumModal || {};
|
||||
const story = selectPeerStory(global, peerId, storyId);
|
||||
const isLoadedStory = story && 'content' in story;
|
||||
const shouldForcePause = Boolean(
|
||||
viewModal || forwardedStoryId || tabState.reactionPicker?.storyId || isReportModalOpen || isPrivacyModalOpen
|
||||
|| isPremiumModalOpen || isDeleteModalOpen || safeLinkModalUrl || isStealthModalOpen || mapModal,
|
||||
);
|
||||
|
||||
const forwardInfo = (story && 'forwardInfo' in story) ? story.forwardInfo : undefined;
|
||||
const mediaAreas = (story && 'mediaAreas' in story) ? story.mediaAreas : undefined;
|
||||
const forwardInfo = isLoadedStory ? story.forwardInfo : undefined;
|
||||
const mediaAreas = isLoadedStory ? story.mediaAreas : undefined;
|
||||
const forwardSenderId = forwardInfo?.fromPeerId
|
||||
|| mediaAreas?.find((area): area is ApiMediaAreaChannelPost => area.type === 'channelPost')?.channelId;
|
||||
const forwardSender = forwardSenderId ? selectPeer(global, forwardSenderId) : undefined;
|
||||
const withHeaderAnimation = selectPerformanceSettingsValue(global, 'mediaViewerAnimations');
|
||||
|
||||
const fromPeer = isLoadedStory && story.fromId ? selectPeer(global, story.fromId) : undefined;
|
||||
|
||||
return {
|
||||
peer: (user || chat)!,
|
||||
forwardSender,
|
||||
fromPeer,
|
||||
story,
|
||||
orderedIds: storyList?.storyIdsByPeerId[peerId],
|
||||
isMuted,
|
||||
|
||||
@ -19,13 +19,11 @@ import styles from './StoryFooter.module.scss';
|
||||
|
||||
type OwnProps = {
|
||||
story: ApiStory;
|
||||
areViewsExpired?: boolean;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const StoryFooter = ({
|
||||
story,
|
||||
areViewsExpired,
|
||||
className,
|
||||
}: OwnProps) => {
|
||||
const { openStoryViewModal, openForwardMenu, sendStoryReaction } = getActions();
|
||||
@ -94,7 +92,7 @@ const StoryFooter = ({
|
||||
className={buildClassName(styles.viewInfo, !isChannel && styles.interactive)}
|
||||
onClick={!isChannel ? handleOpenStoryViewModal : undefined}
|
||||
>
|
||||
{!areViewsExpired && Boolean(recentViewers?.length) && (
|
||||
{Boolean(recentViewers?.length) && (
|
||||
<AvatarList
|
||||
size="small"
|
||||
peers={recentViewers}
|
||||
|
||||
@ -58,7 +58,7 @@ function StoryViewModal({
|
||||
isCurrentUserPremium,
|
||||
}: StateProps) {
|
||||
const {
|
||||
loadStoryViews, closeStoryViewModal, clearStoryViews,
|
||||
loadStoryViewList, closeStoryViewModal, clearStoryViews,
|
||||
} = getActions();
|
||||
|
||||
const [areJustContacts, markJustContacts, unmarkJustContacts] = useFlag(false);
|
||||
@ -102,7 +102,7 @@ function StoryViewModal({
|
||||
|
||||
const handleLoadMore = useLastCallback(() => {
|
||||
if (!story?.id || nextOffset === undefined) return;
|
||||
loadStoryViews({
|
||||
loadStoryViewList({
|
||||
peerId: story.peerId,
|
||||
storyId: story.id,
|
||||
offset: nextOffset,
|
||||
|
||||
@ -737,17 +737,17 @@
|
||||
|
||||
&.clickable {
|
||||
cursor: var(--custom-cursor, pointer);
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.forwardHeaderText {
|
||||
.headerTitle {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
.forwardHeader.clickable:hover & {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.forwardInfo {
|
||||
@ -759,3 +759,14 @@
|
||||
margin-bottom: 0.5rem;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.fromPeer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
cursor: var(--custom-cursor, pointer);
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ export const CUSTOM_EMOJI_PREVIEW_CACHE_DISABLED = false;
|
||||
export const CUSTOM_EMOJI_PREVIEW_CACHE_NAME = 'tt-custom-emoji-preview';
|
||||
export const MEDIA_CACHE_MAX_BYTES = 512 * 1024; // 512 KB
|
||||
export const CUSTOM_BG_CACHE_NAME = 'tt-custom-bg';
|
||||
export const LANG_CACHE_NAME = 'tt-lang-packs-v31';
|
||||
export const LANG_CACHE_NAME = 'tt-lang-packs-v32';
|
||||
export const ASSET_CACHE_NAME = 'tt-assets';
|
||||
export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500];
|
||||
export const DATA_BROADCAST_CHANNEL_NAME = 'tt-global';
|
||||
@ -206,7 +206,6 @@ export const POPULAR_SYMBOL_SET_ID = 'popular';
|
||||
export const RECENT_SYMBOL_SET_ID = 'recent';
|
||||
export const FAVORITE_SYMBOL_SET_ID = 'favorite';
|
||||
export const CHAT_STICKER_SET_ID = 'chatStickers';
|
||||
export const PREMIUM_STICKER_SET_ID = 'premium';
|
||||
export const DEFAULT_TOPIC_ICON_STICKER_ID = 'topic-default-icon';
|
||||
export const DEFAULT_STATUS_ICON_ID = 'status-default-icon';
|
||||
export const EMOJI_IMG_REGEX = /<img[^>]+alt="([^"]+)"(?![^>]*data-document-id)[^>]*>/gm;
|
||||
|
||||
@ -1463,7 +1463,7 @@ addActionHandler('processBoostParameters', async (global, actions, payload): Pro
|
||||
}
|
||||
}
|
||||
|
||||
if (!isChatChannel(chat)) {
|
||||
if (!isChatChannel(chat) && !isChatSuperGroup(chat)) {
|
||||
actions.openChat({ id: chat.id, tabId });
|
||||
return;
|
||||
}
|
||||
@ -2781,13 +2781,12 @@ export async function loadFullChat<T extends GlobalState>(
|
||||
}
|
||||
|
||||
const {
|
||||
users, userStatusesById, fullInfo, groupCall, membersCount, isForumAsMessages,
|
||||
chats, users, userStatusesById, fullInfo, groupCall, membersCount, isForumAsMessages,
|
||||
} = result;
|
||||
|
||||
global = getGlobal();
|
||||
if (users) {
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
}
|
||||
global = addUsers(global, buildCollectionByKey(users, 'id'));
|
||||
global = updateChats(global, buildCollectionByKey(chats, 'id'));
|
||||
|
||||
if (userStatusesById) {
|
||||
global = addUserStatuses(global, userStatusesById);
|
||||
@ -2825,6 +2824,18 @@ export async function loadFullChat<T extends GlobalState>(
|
||||
});
|
||||
}
|
||||
|
||||
const emojiSet = fullInfo.emojiSet;
|
||||
const localEmojiSet = emojiSet && selectStickerSet(global, emojiSet);
|
||||
if (emojiSet && !localEmojiSet) {
|
||||
actions.loadStickers({
|
||||
stickerSetInfo: {
|
||||
id: emojiSet.id,
|
||||
accessHash: emojiSet.accessHash,
|
||||
},
|
||||
tabId,
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -312,7 +312,7 @@ addActionHandler('sendMessage', (global, actions, payload): ActionReturnType =>
|
||||
|
||||
const storyReplyInfo = isStoryReply ? {
|
||||
type: 'story',
|
||||
userId: storyPeerId!,
|
||||
peerId: storyPeerId!,
|
||||
storyId: storyId!,
|
||||
} satisfies ApiInputStoryReplyInfo : undefined;
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import { buildCollectionByKey, unique } from '../../../util/iteratees';
|
||||
import * as langProvider from '../../../util/langProvider';
|
||||
import { buildQueryString } from '../../../util/requestQuery';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { getStripeError, isChatChannel } from '../../helpers';
|
||||
import { getStripeError, isChatChannel, isChatSuperGroup } from '../../helpers';
|
||||
import { addActionHandler, getGlobal, setGlobal } from '../../index';
|
||||
import {
|
||||
addChats,
|
||||
@ -19,12 +19,14 @@ import {
|
||||
setReceipt,
|
||||
setRequestInfoId,
|
||||
setSmartGlocalCardInfo, setStripeCardInfo,
|
||||
updateChatFullInfo,
|
||||
updatePayment,
|
||||
updateShippingOptions,
|
||||
} from '../../reducers';
|
||||
import { updateTabState } from '../../reducers/tabs';
|
||||
import {
|
||||
selectChat,
|
||||
selectChatFullInfo,
|
||||
selectChatMessage,
|
||||
selectPaymentFormId,
|
||||
selectPaymentInputInvoice, selectPaymentRequestId,
|
||||
@ -36,6 +38,8 @@ import {
|
||||
selectUser,
|
||||
} from '../../selectors';
|
||||
|
||||
const LOCAL_BOOST_COOLDOWN = 86400; // 24 hours
|
||||
|
||||
addActionHandler('validateRequestedInfo', (global, actions, payload): ActionReturnType => {
|
||||
const { requestInfo, saveInfo, tabId = getCurrentTabId() } = payload;
|
||||
|
||||
@ -477,7 +481,7 @@ async function validateRequestedInfo<T extends GlobalState>(
|
||||
addActionHandler('openBoostModal', async (global, actions, payload): Promise<void> => {
|
||||
const { chatId, tabId = getCurrentTabId() } = payload;
|
||||
const chat = selectChat(global, chatId);
|
||||
if (!chat || !isChatChannel(chat)) return;
|
||||
if (!chat || !(isChatChannel(chat) || isChatSuperGroup(chat))) return;
|
||||
|
||||
global = updateTabState(global, {
|
||||
boostModal: {
|
||||
@ -614,19 +618,96 @@ addActionHandler('applyBoost', async (global, actions, payload): Promise<void> =
|
||||
const chat = selectChat(global, chatId);
|
||||
if (!chat) return;
|
||||
|
||||
const oldChatFullInfo = selectChatFullInfo(global, chatId);
|
||||
const oldBoostsApplied = oldChatFullInfo?.boostsApplied || 0;
|
||||
|
||||
const appliedBoostsCount = slots.length;
|
||||
|
||||
let tabState = selectTabState(global, tabId);
|
||||
const oldStatus = tabState.boostModal?.boostStatus;
|
||||
|
||||
if (oldStatus) {
|
||||
const boostsPerLevel = oldStatus.nextLevelBoosts ? oldStatus.nextLevelBoosts - oldStatus.currentLevelBoosts : 1;
|
||||
const newBoosts = oldStatus.boosts + appliedBoostsCount;
|
||||
const isLevelUp = oldStatus.nextLevelBoosts && newBoosts >= oldStatus.nextLevelBoosts;
|
||||
const newCurrentLevelBoosts = isLevelUp ? oldStatus.nextLevelBoosts! : oldStatus.currentLevelBoosts;
|
||||
const newNextLevelBoosts = isLevelUp ? oldStatus.nextLevelBoosts! + boostsPerLevel : oldStatus.nextLevelBoosts;
|
||||
|
||||
global = updateTabState(global, {
|
||||
boostModal: {
|
||||
...tabState.boostModal!,
|
||||
boostStatus: {
|
||||
...oldStatus,
|
||||
level: isLevelUp ? oldStatus.level + 1 : oldStatus.level,
|
||||
currentLevelBoosts: newCurrentLevelBoosts,
|
||||
nextLevelBoosts: newNextLevelBoosts,
|
||||
hasMyBoost: true,
|
||||
boosts: newBoosts,
|
||||
},
|
||||
},
|
||||
}, tabId);
|
||||
setGlobal(global);
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
tabState = selectTabState(global, tabId);
|
||||
const oldMyBoosts = tabState.boostModal?.myBoosts;
|
||||
|
||||
if (oldMyBoosts) {
|
||||
const unixNow = Math.floor(Date.now() / 1000);
|
||||
const newMyBoosts = oldMyBoosts.map((boost) => {
|
||||
if (slots.includes(boost.slot)) {
|
||||
return {
|
||||
...boost,
|
||||
chatId,
|
||||
date: unixNow,
|
||||
cooldownUntil: unixNow + LOCAL_BOOST_COOLDOWN, // Will be refetched below
|
||||
};
|
||||
}
|
||||
return boost;
|
||||
});
|
||||
|
||||
global = updateTabState(global, {
|
||||
boostModal: {
|
||||
...tabState.boostModal!,
|
||||
myBoosts: newMyBoosts,
|
||||
},
|
||||
}, tabId);
|
||||
setGlobal(global);
|
||||
}
|
||||
|
||||
const result = await callApi('applyBoost', {
|
||||
slots,
|
||||
chat,
|
||||
});
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
if (!result) {
|
||||
// Rollback local changes
|
||||
const boostModal = selectTabState(global, tabId).boostModal;
|
||||
if (boostModal) {
|
||||
global = updateTabState(global, {
|
||||
boostModal: {
|
||||
...boostModal,
|
||||
boostStatus: oldStatus,
|
||||
myBoosts: oldMyBoosts,
|
||||
},
|
||||
}, tabId);
|
||||
setGlobal(global);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
let tabState = selectTabState(global, tabId);
|
||||
tabState = selectTabState(global, tabId);
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
if (oldChatFullInfo) {
|
||||
global = updateChatFullInfo(global, chatId, {
|
||||
boostsApplied: oldBoostsApplied + slots.length,
|
||||
});
|
||||
}
|
||||
|
||||
if (tabState.boostModal) {
|
||||
global = updateTabState(global, {
|
||||
boostModal: {
|
||||
@ -636,25 +717,6 @@ addActionHandler('applyBoost', async (global, actions, payload): Promise<void> =
|
||||
}, tabId);
|
||||
}
|
||||
setGlobal(global);
|
||||
|
||||
const newStatusResult = await callApi('fetchBoostsStatus', {
|
||||
chat,
|
||||
});
|
||||
|
||||
if (!newStatusResult) {
|
||||
return;
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
tabState = selectTabState(global, tabId);
|
||||
if (!tabState.boostModal?.boostStatus) return;
|
||||
global = updateTabState(global, {
|
||||
boostModal: {
|
||||
...tabState.boostModal,
|
||||
boostStatus: newStatusResult,
|
||||
},
|
||||
}, tabId);
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
addActionHandler('checkGiftCode', async (global, actions, payload): Promise<void> => {
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import type { ApiStoryView } from '../../../api/types';
|
||||
import type { ActionReturnType } from '../../types';
|
||||
|
||||
import { DEBUG, PREVIEW_AVATAR_COUNT } from '../../../config';
|
||||
import { DEBUG } from '../../../config';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { translate } from '../../../util/langProvider';
|
||||
@ -312,31 +311,43 @@ addActionHandler('loadPeerStoriesByIds', async (global, actions, payload): Promi
|
||||
});
|
||||
|
||||
addActionHandler('loadStoryViews', async (global, actions, payload): Promise<void> => {
|
||||
const { peerId, storyId } = payload;
|
||||
const peer = selectPeer(global, peerId);
|
||||
if (!peer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await callApi('fetchStoriesViews', { peer, storyIds: [storyId] });
|
||||
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = updatePeerStoryViews(global, peerId, storyId, result.views);
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
addActionHandler('loadStoryViewList', async (global, actions, payload): Promise<void> => {
|
||||
const {
|
||||
peerId,
|
||||
storyId,
|
||||
offset,
|
||||
areReactionsFirst,
|
||||
areJustContacts,
|
||||
query,
|
||||
limit,
|
||||
tabId = getCurrentTabId(),
|
||||
} = payload;
|
||||
const isPreload = 'isPreload' in payload;
|
||||
const {
|
||||
offset, areReactionsFirst, areJustContacts, query, limit,
|
||||
} = isPreload ? {
|
||||
offset: undefined,
|
||||
areReactionsFirst: undefined,
|
||||
areJustContacts: undefined,
|
||||
query: undefined,
|
||||
limit: PREVIEW_AVATAR_COUNT,
|
||||
} : payload;
|
||||
|
||||
const peer = selectPeer(global, peerId);
|
||||
if (!peer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isPreload) {
|
||||
global = updateStoryViewsLoading(global, true, tabId);
|
||||
setGlobal(global);
|
||||
}
|
||||
global = updateStoryViewsLoading(global, true, tabId);
|
||||
setGlobal(global);
|
||||
|
||||
const result = await callApi('fetchStoryViewList', {
|
||||
peer,
|
||||
@ -357,18 +368,7 @@ addActionHandler('loadStoryViews', async (global, actions, payload): Promise<voi
|
||||
global = getGlobal();
|
||||
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
|
||||
global = addChats(global, buildCollectionByKey(result.chats, 'id'));
|
||||
if (!isPreload) global = updateStoryViews(global, storyId, result.views, result.nextOffset, tabId);
|
||||
|
||||
if (isPreload && result.views?.length) {
|
||||
const recentViewerIds = result.views
|
||||
.filter((view): view is ApiStoryView => 'date' in view)
|
||||
.map((view) => view.peerId);
|
||||
global = updatePeerStoryViews(global, peerId, storyId, {
|
||||
recentViewerIds,
|
||||
viewsCount: result.viewsCount,
|
||||
reactionsCount: result.reactionsCount,
|
||||
});
|
||||
}
|
||||
global = updateStoryViews(global, storyId, result.views, result.nextOffset, tabId);
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
|
||||
@ -149,29 +149,6 @@ addActionHandler('loadPremiumStickers', async (global): Promise<void> => {
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
addActionHandler('loadPremiumSetStickers', async (global): Promise<void> => {
|
||||
const { hash } = global.stickers.premium || {};
|
||||
|
||||
const result = await callApi('fetchStickersForEmoji', { emoji: '📂⭐️', hash });
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
global = {
|
||||
...global,
|
||||
stickers: {
|
||||
...global.stickers,
|
||||
premiumSet: {
|
||||
hash: result.hash,
|
||||
stickers: result.stickers,
|
||||
},
|
||||
},
|
||||
};
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
addActionHandler('loadGreetingStickers', async (global): Promise<void> => {
|
||||
const { hash } = global.stickers.greeting || {};
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ import { updateTabState } from '../../reducers/tabs';
|
||||
import {
|
||||
selectCanAnimateInterface,
|
||||
selectChat,
|
||||
selectChatFullInfo,
|
||||
selectChatMessage,
|
||||
selectCurrentChat,
|
||||
selectCurrentMessageList,
|
||||
@ -319,11 +320,12 @@ addActionHandler('showAllowedMessageTypesNotification', (global, actions, payloa
|
||||
|
||||
const chat = selectChat(global, chatId);
|
||||
if (!chat) return;
|
||||
const chatFullInfo = selectChatFullInfo(global, chatId);
|
||||
|
||||
const {
|
||||
canSendPlainText, canSendPhotos, canSendVideos, canSendDocuments, canSendAudios,
|
||||
canSendStickers, canSendRoundVideos, canSendVoices,
|
||||
} = getAllowedAttachmentOptions(chat);
|
||||
} = getAllowedAttachmentOptions(chat, chatFullInfo);
|
||||
const allowedContent = compact([
|
||||
canSendPlainText ? 'Chat.SendAllowedContentTypeText' : undefined,
|
||||
canSendPhotos ? 'Chat.SendAllowedContentTypePhoto' : undefined,
|
||||
|
||||
@ -3,6 +3,7 @@ import type {
|
||||
ApiChatAdminRights,
|
||||
ApiChatBannedRights,
|
||||
ApiChatFolder,
|
||||
ApiChatFullInfo,
|
||||
ApiPeer,
|
||||
ApiTopic,
|
||||
ApiUser,
|
||||
@ -130,14 +131,18 @@ export function getCanManageTopic(chat: ApiChat, topic: ApiTopic) {
|
||||
return chat.isCreator || getHasAdminRight(chat, 'manageTopics') || topic.isOwner;
|
||||
}
|
||||
|
||||
export function isUserRightBanned(chat: ApiChat, key: keyof ApiChatBannedRights) {
|
||||
export function isUserRightBanned(chat: ApiChat, key: keyof ApiChatBannedRights, chatFullInfo?: ApiChatFullInfo) {
|
||||
const unrestrictedByBoosts = chatFullInfo?.boostsToUnrestrict
|
||||
&& (chatFullInfo.boostsApplied || 0) >= chatFullInfo.boostsToUnrestrict;
|
||||
return Boolean(
|
||||
(chat.currentUserBannedRights?.[key])
|
||||
|| (chat.defaultBannedRights?.[key]),
|
||||
|| (chat.defaultBannedRights?.[key] && !unrestrictedByBoosts),
|
||||
);
|
||||
}
|
||||
|
||||
export function getCanPostInChat(chat: ApiChat, threadId: ThreadId, isMessageThread?: boolean) {
|
||||
export function getCanPostInChat(
|
||||
chat: ApiChat, threadId: ThreadId, isMessageThread?: boolean, chatFullInfo?: ApiChatFullInfo,
|
||||
) {
|
||||
if (threadId !== MAIN_THREAD_ID) {
|
||||
if (chat.isForum) {
|
||||
if (chat.isNotJoined) {
|
||||
@ -168,7 +173,7 @@ export function getCanPostInChat(chat: ApiChat, threadId: ThreadId, isMessageThr
|
||||
return getHasAdminRight(chat, 'postMessages');
|
||||
}
|
||||
|
||||
return isChatAdmin(chat) || !isUserRightBanned(chat, 'sendMessages');
|
||||
return isChatAdmin(chat) || !isUserRightBanned(chat, 'sendMessages', chatFullInfo);
|
||||
}
|
||||
|
||||
export interface IAllowedAttachmentOptions {
|
||||
@ -188,6 +193,7 @@ export interface IAllowedAttachmentOptions {
|
||||
|
||||
export function getAllowedAttachmentOptions(
|
||||
chat?: ApiChat,
|
||||
chatFullInfo?: ApiChatFullInfo,
|
||||
isChatWithBot = false,
|
||||
isStoryReply = false,
|
||||
): IAllowedAttachmentOptions {
|
||||
@ -211,20 +217,20 @@ export function getAllowedAttachmentOptions(
|
||||
const isAdmin = isChatAdmin(chat);
|
||||
|
||||
return {
|
||||
canAttachMedia: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendMedia'),
|
||||
canAttachMedia: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendMedia', chatFullInfo),
|
||||
canAttachPolls: !isStoryReply
|
||||
&& (isAdmin || !isUserRightBanned(chat, 'sendPolls'))
|
||||
&& (isAdmin || !isUserRightBanned(chat, 'sendPolls', chatFullInfo))
|
||||
&& (!isUserId(chat.id) || isChatWithBot),
|
||||
canSendStickers: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendStickers'),
|
||||
canSendGifs: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendGifs'),
|
||||
canAttachEmbedLinks: !isStoryReply && (isAdmin || !isUserRightBanned(chat, 'embedLinks')),
|
||||
canSendPhotos: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendPhotos'),
|
||||
canSendVideos: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendVideos'),
|
||||
canSendRoundVideos: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendRoundvideos'),
|
||||
canSendAudios: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendAudios'),
|
||||
canSendVoices: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendVoices'),
|
||||
canSendPlainText: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendPlain'),
|
||||
canSendDocuments: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendDocs'),
|
||||
canSendStickers: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendStickers', chatFullInfo),
|
||||
canSendGifs: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendGifs', chatFullInfo),
|
||||
canAttachEmbedLinks: !isStoryReply && (isAdmin || !isUserRightBanned(chat, 'embedLinks', chatFullInfo)),
|
||||
canSendPhotos: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendPhotos', chatFullInfo),
|
||||
canSendVideos: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendVideos', chatFullInfo),
|
||||
canSendRoundVideos: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendRoundvideos', chatFullInfo),
|
||||
canSendAudios: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendAudios', chatFullInfo),
|
||||
canSendVoices: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendVoices', chatFullInfo),
|
||||
canSendPlainText: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendPlain', chatFullInfo),
|
||||
canSendDocuments: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendDocs', chatFullInfo),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -172,9 +172,6 @@ export const INITIAL_GLOBAL_STATE: GlobalState = {
|
||||
premium: {
|
||||
stickers: [],
|
||||
},
|
||||
premiumSet: {
|
||||
stickers: [],
|
||||
},
|
||||
featured: {
|
||||
setIds: [],
|
||||
},
|
||||
|
||||
@ -591,6 +591,8 @@ export function selectAllowedMessageActions<T extends GlobalState>(global: T, me
|
||||
const { content } = message;
|
||||
const messageTopic = selectTopicFromMessage(global, message);
|
||||
const isDocumentSticker = isMessageDocumentSticker(message);
|
||||
const chatFullInfo = selectChatFullInfo(global, chat.id);
|
||||
const isBoostMessage = message.content.action?.type === 'chatBoost';
|
||||
|
||||
const canEditMessagesIndefinitely = isChatWithSelf
|
||||
|| (isSuperGroup && getHasAdminRight(chat, 'pinMessages'))
|
||||
@ -614,7 +616,7 @@ export function selectAllowedMessageActions<T extends GlobalState>(global: T, me
|
||||
const threadInfo = selectThreadInfo(global, message.chatId, threadId);
|
||||
const isMessageThread = Boolean(!threadInfo?.isCommentsInfo && threadInfo?.fromChannelId);
|
||||
const canReply = !isLocal && !isServiceNotification && !chat.isForbidden
|
||||
&& getCanPostInChat(chat, threadId, isMessageThread)
|
||||
&& getCanPostInChat(chat, threadId, isMessageThread, chatFullInfo)
|
||||
&& (!messageTopic || !messageTopic.isClosed || messageTopic.isOwner || getHasAdminRight(chat, 'manageTopics'));
|
||||
|
||||
const hasPinPermission = isPrivate || (
|
||||
@ -633,7 +635,10 @@ export function selectAllowedMessageActions<T extends GlobalState>(global: T, me
|
||||
canPin = !canUnpin;
|
||||
}
|
||||
|
||||
const canDelete = (!isLocal || isFailed) && !isServiceNotification && (
|
||||
const canNotDeleteBoostMessage = isBoostMessage && isOwn
|
||||
&& !chat.isCreator && !getHasAdminRight(chat, 'deleteMessages');
|
||||
|
||||
const canDelete = (!isLocal || isFailed) && !isServiceNotification && !canNotDeleteBoostMessage && (
|
||||
isPrivate
|
||||
|| isOwn
|
||||
|| isBasicGroup
|
||||
@ -1363,11 +1368,12 @@ export function selectForwardsCanBeSentToChat<T extends GlobalState>(
|
||||
return true;
|
||||
}
|
||||
|
||||
const chatFullInfo = selectChatFullInfo(global, toChatId);
|
||||
const chatMessages = selectChatMessages(global, fromChatId!);
|
||||
const {
|
||||
canSendVoices, canSendRoundVideos, canSendStickers, canSendDocuments, canSendAudios, canSendVideos,
|
||||
canSendPhotos, canSendGifs, canSendPlainText,
|
||||
} = getAllowedAttachmentOptions(chat);
|
||||
} = getAllowedAttachmentOptions(chat, chatFullInfo);
|
||||
return !messageIds!.some((messageId) => {
|
||||
const message = chatMessages[messageId];
|
||||
const isVoice = message.content.voice;
|
||||
|
||||
@ -910,10 +910,6 @@ export type GlobalState = {
|
||||
hash?: string;
|
||||
stickers: ApiSticker[];
|
||||
};
|
||||
premiumSet: {
|
||||
hash?: string;
|
||||
stickers: ApiSticker[];
|
||||
};
|
||||
featured: {
|
||||
hash?: string;
|
||||
setIds?: string[];
|
||||
@ -2212,11 +2208,11 @@ export interface ActionPayloads {
|
||||
isMuted: boolean;
|
||||
} & WithTabId;
|
||||
closeStoryViewer: WithTabId | undefined;
|
||||
loadStoryViews: ({
|
||||
loadStoryViews: {
|
||||
peerId: string;
|
||||
storyId: number;
|
||||
isPreload: true;
|
||||
} | {
|
||||
};
|
||||
loadStoryViewList: ({
|
||||
peerId: string;
|
||||
storyId: number;
|
||||
offset?: string;
|
||||
@ -2900,9 +2896,6 @@ export interface ActionPayloads {
|
||||
loadPremiumGifts: undefined;
|
||||
loadDefaultTopicIcons: undefined;
|
||||
loadPremiumStickers: undefined;
|
||||
loadPremiumSetStickers: {
|
||||
hash?: string;
|
||||
} | undefined;
|
||||
|
||||
openGiftPremiumModal: ({
|
||||
forUserId?: string;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const api = require('./api');
|
||||
|
||||
const LAYER = 173;
|
||||
const LAYER = 174;
|
||||
const tlobjects = {};
|
||||
|
||||
for (const tl of Object.values(api)) {
|
||||
|
||||
52
src/lib/gramjs/tl/api.d.ts
vendored
52
src/lib/gramjs/tl/api.d.ts
vendored
@ -70,7 +70,7 @@ namespace Api {
|
||||
export type TypeChatPhoto = ChatPhotoEmpty | ChatPhoto;
|
||||
export type TypeMessage = MessageEmpty | Message | MessageService;
|
||||
export type TypeMessageMedia = MessageMediaEmpty | MessageMediaPhoto | MessageMediaGeo | MessageMediaContact | MessageMediaUnsupported | MessageMediaDocument | MessageMediaWebPage | MessageMediaVenue | MessageMediaGame | MessageMediaInvoice | MessageMediaGeoLive | MessageMediaPoll | MessageMediaDice | MessageMediaStory | MessageMediaGiveaway | MessageMediaGiveawayResults;
|
||||
export type TypeMessageAction = MessageActionEmpty | MessageActionChatCreate | MessageActionChatEditTitle | MessageActionChatEditPhoto | MessageActionChatDeletePhoto | MessageActionChatAddUser | MessageActionChatDeleteUser | MessageActionChatJoinedByLink | MessageActionChannelCreate | MessageActionChatMigrateTo | MessageActionChannelMigrateFrom | MessageActionPinMessage | MessageActionHistoryClear | MessageActionGameScore | MessageActionPaymentSentMe | MessageActionPaymentSent | MessageActionPhoneCall | MessageActionScreenshotTaken | MessageActionCustomAction | MessageActionBotAllowed | MessageActionSecureValuesSentMe | MessageActionSecureValuesSent | MessageActionContactSignUp | MessageActionGeoProximityReached | MessageActionGroupCall | MessageActionInviteToGroupCall | MessageActionSetMessagesTTL | MessageActionGroupCallScheduled | MessageActionSetChatTheme | MessageActionChatJoinedByRequest | MessageActionWebViewDataSentMe | MessageActionWebViewDataSent | MessageActionGiftPremium | MessageActionTopicCreate | MessageActionTopicEdit | MessageActionSuggestProfilePhoto | MessageActionRequestedPeer | MessageActionSetChatWallPaper | MessageActionGiftCode | MessageActionGiveawayLaunch | MessageActionGiveawayResults;
|
||||
export type TypeMessageAction = MessageActionEmpty | MessageActionChatCreate | MessageActionChatEditTitle | MessageActionChatEditPhoto | MessageActionChatDeletePhoto | MessageActionChatAddUser | MessageActionChatDeleteUser | MessageActionChatJoinedByLink | MessageActionChannelCreate | MessageActionChatMigrateTo | MessageActionChannelMigrateFrom | MessageActionPinMessage | MessageActionHistoryClear | MessageActionGameScore | MessageActionPaymentSentMe | MessageActionPaymentSent | MessageActionPhoneCall | MessageActionScreenshotTaken | MessageActionCustomAction | MessageActionBotAllowed | MessageActionSecureValuesSentMe | MessageActionSecureValuesSent | MessageActionContactSignUp | MessageActionGeoProximityReached | MessageActionGroupCall | MessageActionInviteToGroupCall | MessageActionSetMessagesTTL | MessageActionGroupCallScheduled | MessageActionSetChatTheme | MessageActionChatJoinedByRequest | MessageActionWebViewDataSentMe | MessageActionWebViewDataSent | MessageActionGiftPremium | MessageActionTopicCreate | MessageActionTopicEdit | MessageActionSuggestProfilePhoto | MessageActionRequestedPeer | MessageActionSetChatWallPaper | MessageActionGiftCode | MessageActionGiveawayLaunch | MessageActionGiveawayResults | MessageActionBoostApply;
|
||||
export type TypeDialog = Dialog | DialogFolder;
|
||||
export type TypePhoto = PhotoEmpty | Photo;
|
||||
export type TypePhotoSize = PhotoSizeEmpty | PhotoSize | PhotoCachedSize | PhotoStrippedSize | PhotoSizeProgressive | PhotoPathSize;
|
||||
@ -168,7 +168,7 @@ namespace Api {
|
||||
export type TypeLangPackString = LangPackString | LangPackStringPluralized | LangPackStringDeleted;
|
||||
export type TypeLangPackDifference = LangPackDifference;
|
||||
export type TypeLangPackLanguage = LangPackLanguage;
|
||||
export type TypeChannelAdminLogEventAction = ChannelAdminLogEventActionChangeTitle | ChannelAdminLogEventActionChangeAbout | ChannelAdminLogEventActionChangeUsername | ChannelAdminLogEventActionChangePhoto | ChannelAdminLogEventActionToggleInvites | ChannelAdminLogEventActionToggleSignatures | ChannelAdminLogEventActionUpdatePinned | ChannelAdminLogEventActionEditMessage | ChannelAdminLogEventActionDeleteMessage | ChannelAdminLogEventActionParticipantJoin | ChannelAdminLogEventActionParticipantLeave | ChannelAdminLogEventActionParticipantInvite | ChannelAdminLogEventActionParticipantToggleBan | ChannelAdminLogEventActionParticipantToggleAdmin | ChannelAdminLogEventActionChangeStickerSet | ChannelAdminLogEventActionTogglePreHistoryHidden | ChannelAdminLogEventActionDefaultBannedRights | ChannelAdminLogEventActionStopPoll | ChannelAdminLogEventActionChangeLinkedChat | ChannelAdminLogEventActionChangeLocation | ChannelAdminLogEventActionToggleSlowMode | ChannelAdminLogEventActionStartGroupCall | ChannelAdminLogEventActionDiscardGroupCall | ChannelAdminLogEventActionParticipantMute | ChannelAdminLogEventActionParticipantUnmute | ChannelAdminLogEventActionToggleGroupCallSetting | ChannelAdminLogEventActionParticipantJoinByInvite | ChannelAdminLogEventActionExportedInviteDelete | ChannelAdminLogEventActionExportedInviteRevoke | ChannelAdminLogEventActionExportedInviteEdit | ChannelAdminLogEventActionParticipantVolume | ChannelAdminLogEventActionChangeHistoryTTL | ChannelAdminLogEventActionParticipantJoinByRequest | ChannelAdminLogEventActionToggleNoForwards | ChannelAdminLogEventActionSendMessage | ChannelAdminLogEventActionChangeAvailableReactions | ChannelAdminLogEventActionChangeUsernames | ChannelAdminLogEventActionToggleForum | ChannelAdminLogEventActionCreateTopic | ChannelAdminLogEventActionEditTopic | ChannelAdminLogEventActionDeleteTopic | ChannelAdminLogEventActionPinTopic | ChannelAdminLogEventActionToggleAntiSpam | ChannelAdminLogEventActionChangePeerColor | ChannelAdminLogEventActionChangeProfilePeerColor | ChannelAdminLogEventActionChangeWallpaper | ChannelAdminLogEventActionChangeEmojiStatus;
|
||||
export type TypeChannelAdminLogEventAction = ChannelAdminLogEventActionChangeTitle | ChannelAdminLogEventActionChangeAbout | ChannelAdminLogEventActionChangeUsername | ChannelAdminLogEventActionChangePhoto | ChannelAdminLogEventActionToggleInvites | ChannelAdminLogEventActionToggleSignatures | ChannelAdminLogEventActionUpdatePinned | ChannelAdminLogEventActionEditMessage | ChannelAdminLogEventActionDeleteMessage | ChannelAdminLogEventActionParticipantJoin | ChannelAdminLogEventActionParticipantLeave | ChannelAdminLogEventActionParticipantInvite | ChannelAdminLogEventActionParticipantToggleBan | ChannelAdminLogEventActionParticipantToggleAdmin | ChannelAdminLogEventActionChangeStickerSet | ChannelAdminLogEventActionTogglePreHistoryHidden | ChannelAdminLogEventActionDefaultBannedRights | ChannelAdminLogEventActionStopPoll | ChannelAdminLogEventActionChangeLinkedChat | ChannelAdminLogEventActionChangeLocation | ChannelAdminLogEventActionToggleSlowMode | ChannelAdminLogEventActionStartGroupCall | ChannelAdminLogEventActionDiscardGroupCall | ChannelAdminLogEventActionParticipantMute | ChannelAdminLogEventActionParticipantUnmute | ChannelAdminLogEventActionToggleGroupCallSetting | ChannelAdminLogEventActionParticipantJoinByInvite | ChannelAdminLogEventActionExportedInviteDelete | ChannelAdminLogEventActionExportedInviteRevoke | ChannelAdminLogEventActionExportedInviteEdit | ChannelAdminLogEventActionParticipantVolume | ChannelAdminLogEventActionChangeHistoryTTL | ChannelAdminLogEventActionParticipantJoinByRequest | ChannelAdminLogEventActionToggleNoForwards | ChannelAdminLogEventActionSendMessage | ChannelAdminLogEventActionChangeAvailableReactions | ChannelAdminLogEventActionChangeUsernames | ChannelAdminLogEventActionToggleForum | ChannelAdminLogEventActionCreateTopic | ChannelAdminLogEventActionEditTopic | ChannelAdminLogEventActionDeleteTopic | ChannelAdminLogEventActionPinTopic | ChannelAdminLogEventActionToggleAntiSpam | ChannelAdminLogEventActionChangePeerColor | ChannelAdminLogEventActionChangeProfilePeerColor | ChannelAdminLogEventActionChangeWallpaper | ChannelAdminLogEventActionChangeEmojiStatus | ChannelAdminLogEventActionChangeEmojiStickerSet;
|
||||
export type TypeChannelAdminLogEvent = ChannelAdminLogEvent;
|
||||
export type TypeChannelAdminLogEventsFilter = ChannelAdminLogEventsFilter;
|
||||
export type TypePopularContact = PopularContact;
|
||||
@ -1395,6 +1395,9 @@ namespace Api {
|
||||
availableReactions?: Api.TypeChatReactions;
|
||||
stories?: Api.TypePeerStories;
|
||||
wallpaper?: Api.TypeWallPaper;
|
||||
boostsApplied?: int;
|
||||
boostsUnrestrict?: int;
|
||||
emojiset?: Api.TypeStickerSet;
|
||||
}> {
|
||||
// flags: undefined;
|
||||
canViewParticipants?: true;
|
||||
@ -1449,6 +1452,9 @@ namespace Api {
|
||||
availableReactions?: Api.TypeChatReactions;
|
||||
stories?: Api.TypePeerStories;
|
||||
wallpaper?: Api.TypeWallPaper;
|
||||
boostsApplied?: int;
|
||||
boostsUnrestrict?: int;
|
||||
emojiset?: Api.TypeStickerSet;
|
||||
};
|
||||
export class ChatParticipant extends VirtualClass<{
|
||||
userId: long;
|
||||
@ -1529,6 +1535,7 @@ namespace Api {
|
||||
invertMedia?: true;
|
||||
id: int;
|
||||
fromId?: Api.TypePeer;
|
||||
fromBoostsApplied?: int;
|
||||
peerId: Api.TypePeer;
|
||||
savedPeerId?: Api.TypePeer;
|
||||
fwdFrom?: Api.TypeMessageFwdHeader;
|
||||
@ -1563,6 +1570,7 @@ namespace Api {
|
||||
invertMedia?: true;
|
||||
id: int;
|
||||
fromId?: Api.TypePeer;
|
||||
fromBoostsApplied?: int;
|
||||
peerId: Api.TypePeer;
|
||||
savedPeerId?: Api.TypePeer;
|
||||
fwdFrom?: Api.TypeMessageFwdHeader;
|
||||
@ -2107,6 +2115,11 @@ namespace Api {
|
||||
winnersCount: int;
|
||||
unclaimedCount: int;
|
||||
};
|
||||
export class MessageActionBoostApply extends VirtualClass<{
|
||||
boosts: int;
|
||||
}> {
|
||||
boosts: int;
|
||||
};
|
||||
export class Dialog extends VirtualClass<{
|
||||
// flags: undefined;
|
||||
pinned?: true;
|
||||
@ -6600,6 +6613,13 @@ namespace Api {
|
||||
prevValue: Api.TypeEmojiStatus;
|
||||
newValue: Api.TypeEmojiStatus;
|
||||
};
|
||||
export class ChannelAdminLogEventActionChangeEmojiStickerSet extends VirtualClass<{
|
||||
prevStickerset: Api.TypeInputStickerSet;
|
||||
newStickerset: Api.TypeInputStickerSet;
|
||||
}> {
|
||||
prevStickerset: Api.TypeInputStickerSet;
|
||||
newStickerset: Api.TypeInputStickerSet;
|
||||
};
|
||||
export class ChannelAdminLogEvent extends VirtualClass<{
|
||||
id: long;
|
||||
date: int;
|
||||
@ -7876,10 +7896,10 @@ namespace Api {
|
||||
quoteOffset?: int;
|
||||
};
|
||||
export class MessageReplyStoryHeader extends VirtualClass<{
|
||||
userId: long;
|
||||
peer: Api.TypePeer;
|
||||
storyId: int;
|
||||
}> {
|
||||
userId: long;
|
||||
peer: Api.TypePeer;
|
||||
storyId: int;
|
||||
};
|
||||
export class MessageReplies extends VirtualClass<{
|
||||
@ -8842,6 +8862,7 @@ namespace Api {
|
||||
out?: true;
|
||||
id: int;
|
||||
date: int;
|
||||
fromId?: Api.TypePeer;
|
||||
fwdFrom?: Api.TypeStoryFwdHeader;
|
||||
expireDate: int;
|
||||
caption?: string;
|
||||
@ -8864,6 +8885,7 @@ namespace Api {
|
||||
out?: true;
|
||||
id: int;
|
||||
date: int;
|
||||
fromId?: Api.TypePeer;
|
||||
fwdFrom?: Api.TypeStoryFwdHeader;
|
||||
expireDate: int;
|
||||
caption?: string;
|
||||
@ -8931,10 +8953,10 @@ namespace Api {
|
||||
quoteOffset?: int;
|
||||
};
|
||||
export class InputReplyToStory extends VirtualClass<{
|
||||
userId: Api.TypeInputUser;
|
||||
peer: Api.TypeInputPeer;
|
||||
storyId: int;
|
||||
}> {
|
||||
userId: Api.TypeInputUser;
|
||||
peer: Api.TypeInputPeer;
|
||||
storyId: int;
|
||||
};
|
||||
export class ExportedStoryLink extends VirtualClass<{
|
||||
@ -10839,6 +10861,7 @@ namespace Api {
|
||||
colors?: help.TypePeerColorSet;
|
||||
darkColors?: help.TypePeerColorSet;
|
||||
channelMinLevel?: int;
|
||||
groupMinLevel?: int;
|
||||
}> {
|
||||
// flags: undefined;
|
||||
hidden?: true;
|
||||
@ -10846,6 +10869,7 @@ namespace Api {
|
||||
colors?: help.TypePeerColorSet;
|
||||
darkColors?: help.TypePeerColorSet;
|
||||
channelMinLevel?: int;
|
||||
groupMinLevel?: int;
|
||||
};
|
||||
export class PeerColorsNotModified extends VirtualClass<void> {};
|
||||
export class PeerColors extends VirtualClass<{
|
||||
@ -15506,6 +15530,20 @@ namespace Api {
|
||||
channel: Api.TypeInputChannel;
|
||||
emojiStatus: Api.TypeEmojiStatus;
|
||||
};
|
||||
export class SetBoostsToUnblockRestrictions extends Request<Partial<{
|
||||
channel: Api.TypeInputChannel;
|
||||
boosts: int;
|
||||
}>, Api.TypeUpdates> {
|
||||
channel: Api.TypeInputChannel;
|
||||
boosts: int;
|
||||
};
|
||||
export class SetEmojiStickers extends Request<Partial<{
|
||||
channel: Api.TypeInputChannel;
|
||||
stickerset: Api.TypeInputStickerSet;
|
||||
}>, Bool> {
|
||||
channel: Api.TypeInputChannel;
|
||||
stickerset: Api.TypeInputStickerSet;
|
||||
};
|
||||
}
|
||||
|
||||
export namespace bots {
|
||||
@ -16606,7 +16644,7 @@ namespace Api {
|
||||
| photos.UpdateProfilePhoto | photos.UploadProfilePhoto | photos.DeletePhotos | photos.GetUserPhotos | photos.UploadContactProfilePhoto
|
||||
| upload.SaveFilePart | upload.GetFile | upload.SaveBigFilePart | upload.GetWebFile | upload.GetCdnFile | upload.ReuploadCdnFile | upload.GetCdnFileHashes | upload.GetFileHashes
|
||||
| help.GetConfig | help.GetNearestDc | help.GetAppUpdate | help.GetInviteText | help.GetSupport | help.SetBotUpdatesStatus | help.GetCdnConfig | help.GetRecentMeUrls | help.GetTermsOfServiceUpdate | help.AcceptTermsOfService | help.GetDeepLinkInfo | help.GetAppConfig | help.SaveAppLog | help.GetPassportConfig | help.GetSupportName | help.GetUserInfo | help.EditUserInfo | help.GetPromoData | help.HidePromoData | help.DismissSuggestion | help.GetCountriesList | help.GetPremiumPromo | help.GetPeerColors | help.GetPeerProfileColors
|
||||
| channels.ReadHistory | channels.DeleteMessages | channels.ReportSpam | channels.GetMessages | channels.GetParticipants | channels.GetParticipant | channels.GetChannels | channels.GetFullChannel | channels.CreateChannel | channels.EditAdmin | channels.EditTitle | channels.EditPhoto | channels.CheckUsername | channels.UpdateUsername | channels.JoinChannel | channels.LeaveChannel | channels.InviteToChannel | channels.DeleteChannel | channels.ExportMessageLink | channels.ToggleSignatures | channels.GetAdminedPublicChannels | channels.EditBanned | channels.GetAdminLog | channels.SetStickers | channels.ReadMessageContents | channels.DeleteHistory | channels.TogglePreHistoryHidden | channels.GetLeftChannels | channels.GetGroupsForDiscussion | channels.SetDiscussionGroup | channels.EditCreator | channels.EditLocation | channels.ToggleSlowMode | channels.GetInactiveChannels | channels.ConvertToGigagroup | channels.ViewSponsoredMessage | channels.GetSponsoredMessages | channels.GetSendAs | channels.DeleteParticipantHistory | channels.ToggleJoinToSend | channels.ToggleJoinRequest | channels.ReorderUsernames | channels.ToggleUsername | channels.DeactivateAllUsernames | channels.ToggleForum | channels.CreateForumTopic | channels.GetForumTopics | channels.GetForumTopicsByID | channels.EditForumTopic | channels.UpdatePinnedForumTopic | channels.DeleteTopicHistory | channels.ReorderPinnedForumTopics | channels.ToggleAntiSpam | channels.ReportAntiSpamFalsePositive | channels.ToggleParticipantsHidden | channels.ClickSponsoredMessage | channels.UpdateColor | channels.ToggleViewForumAsMessages | channels.GetChannelRecommendations | channels.UpdateEmojiStatus
|
||||
| channels.ReadHistory | channels.DeleteMessages | channels.ReportSpam | channels.GetMessages | channels.GetParticipants | channels.GetParticipant | channels.GetChannels | channels.GetFullChannel | channels.CreateChannel | channels.EditAdmin | channels.EditTitle | channels.EditPhoto | channels.CheckUsername | channels.UpdateUsername | channels.JoinChannel | channels.LeaveChannel | channels.InviteToChannel | channels.DeleteChannel | channels.ExportMessageLink | channels.ToggleSignatures | channels.GetAdminedPublicChannels | channels.EditBanned | channels.GetAdminLog | channels.SetStickers | channels.ReadMessageContents | channels.DeleteHistory | channels.TogglePreHistoryHidden | channels.GetLeftChannels | channels.GetGroupsForDiscussion | channels.SetDiscussionGroup | channels.EditCreator | channels.EditLocation | channels.ToggleSlowMode | channels.GetInactiveChannels | channels.ConvertToGigagroup | channels.ViewSponsoredMessage | channels.GetSponsoredMessages | channels.GetSendAs | channels.DeleteParticipantHistory | channels.ToggleJoinToSend | channels.ToggleJoinRequest | channels.ReorderUsernames | channels.ToggleUsername | channels.DeactivateAllUsernames | channels.ToggleForum | channels.CreateForumTopic | channels.GetForumTopics | channels.GetForumTopicsByID | channels.EditForumTopic | channels.UpdatePinnedForumTopic | channels.DeleteTopicHistory | channels.ReorderPinnedForumTopics | channels.ToggleAntiSpam | channels.ReportAntiSpamFalsePositive | channels.ToggleParticipantsHidden | channels.ClickSponsoredMessage | channels.UpdateColor | channels.ToggleViewForumAsMessages | channels.GetChannelRecommendations | channels.UpdateEmojiStatus | channels.SetBoostsToUnblockRestrictions | channels.SetEmojiStickers
|
||||
| bots.SendCustomRequest | bots.AnswerWebhookJSONQuery | bots.SetBotCommands | bots.ResetBotCommands | bots.GetBotCommands | bots.SetBotMenuButton | bots.GetBotMenuButton | bots.SetBotBroadcastDefaultAdminRights | bots.SetBotGroupDefaultAdminRights | bots.SetBotInfo | bots.GetBotInfo | bots.ReorderUsernames | bots.ToggleUsername | bots.CanSendMessage | bots.AllowSendMessage | bots.InvokeWebViewCustomMethod
|
||||
| payments.GetPaymentForm | payments.GetPaymentReceipt | payments.ValidateRequestedInfo | payments.SendPaymentForm | payments.GetSavedInfo | payments.ClearSavedInfo | payments.GetBankCardData | payments.ExportInvoice | payments.AssignAppStoreTransaction | payments.AssignPlayMarketTransaction | payments.CanPurchasePremium | payments.GetPremiumGiftCodeOptions | payments.CheckGiftCode | payments.ApplyGiftCode | payments.GetGiveawayInfo | payments.LaunchPrepaidGiveaway
|
||||
| stickers.CreateStickerSet | stickers.RemoveStickerFromSet | stickers.ChangeStickerPosition | stickers.AddStickerToSet | stickers.SetStickerSetThumb | stickers.CheckShortName | stickers.SuggestShortName | stickers.ChangeSticker | stickers.RenameStickerSet | stickers.DeleteStickerSet
|
||||
|
||||
@ -81,7 +81,7 @@ chatForbidden#6592a1a7 id:long title:string = Chat;
|
||||
channel#aadfc8f flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector<Username> stories_max_id:flags2.4?int color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int = Chat;
|
||||
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
|
||||
chatFull#c9d31138 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions = ChatFull;
|
||||
channelFull#f2bcb6f flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper = ChatFull;
|
||||
channelFull#44c054a7 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet = ChatFull;
|
||||
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
|
||||
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
|
||||
chatParticipantAdmin#a0933f5b user_id:long inviter_id:long date:int = ChatParticipant;
|
||||
@ -90,7 +90,7 @@ chatParticipants#3cbc93f8 chat_id:long participants:Vector<ChatParticipant> vers
|
||||
chatPhotoEmpty#37c1011c = ChatPhoto;
|
||||
chatPhoto#1c6e1c11 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = ChatPhoto;
|
||||
messageEmpty#90a6ca84 flags:# id:int peer_id:flags.0?Peer = Message;
|
||||
message#76bec211 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true invert_media:flags.27?true id:int from_id:flags.8?Peer peer_id:Peer saved_peer_id:flags.28?Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector<RestrictionReason> ttl_period:flags.25?int = Message;
|
||||
message#1e4c8a69 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true invert_media:flags.27?true id:int from_id:flags.8?Peer from_boosts_applied:flags.29?int peer_id:Peer saved_peer_id:flags.28?Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector<RestrictionReason> ttl_period:flags.25?int = Message;
|
||||
messageService#2b085862 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?Peer peer_id:Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction ttl_period:flags.25?int = Message;
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
messageMediaPhoto#695150d7 flags:# spoiler:flags.3?true photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
|
||||
@ -149,6 +149,7 @@ messageActionSetChatWallPaper#5060a3f4 flags:# same:flags.0?true for_both:flags.
|
||||
messageActionGiftCode#678c2e09 flags:# via_giveaway:flags.0?true unclaimed:flags.2?true boost_peer:flags.1?Peer months:int slug:string currency:flags.2?string amount:flags.2?long crypto_currency:flags.3?string crypto_amount:flags.3?long = MessageAction;
|
||||
messageActionGiveawayLaunch#332ba9ed = MessageAction;
|
||||
messageActionGiveawayResults#2a9fadc5 winners_count:int unclaimed_count:int = MessageAction;
|
||||
messageActionBoostApply#cc02aa6d boosts:int = MessageAction;
|
||||
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||
photoEmpty#2331b22d id:long = Photo;
|
||||
@ -797,6 +798,7 @@ channelAdminLogEventActionChangePeerColor#5796e780 prev_value:PeerColor new_valu
|
||||
channelAdminLogEventActionChangeProfilePeerColor#5e477b25 prev_value:PeerColor new_value:PeerColor = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeWallpaper#31bb5d52 prev_value:WallPaper new_value:WallPaper = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeEmojiStatus#3ea9feb1 prev_value:EmojiStatus new_value:EmojiStatus = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeEmojiStickerSet#46d840ab prev_stickerset:InputStickerSet new_stickerset:InputStickerSet = 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 forums:flags.17?true = ChannelAdminLogEventsFilter;
|
||||
@ -982,7 +984,7 @@ messageViews#455b853d flags:# views:flags.0?int forwards:flags.1?int replies:fla
|
||||
messages.messageViews#b6c4f543 views:Vector<MessageViews> chats:Vector<Chat> users:Vector<User> = messages.MessageViews;
|
||||
messages.discussionMessage#a6341782 flags:# messages:Vector<Message> max_id:flags.0?int read_inbox_max_id:flags.1?int read_outbox_max_id:flags.2?int unread_count:int chats:Vector<Chat> users:Vector<User> = messages.DiscussionMessage;
|
||||
messageReplyHeader#afbc09db flags:# reply_to_scheduled:flags.2?true forum_topic:flags.3?true quote:flags.9?true reply_to_msg_id:flags.4?int reply_to_peer_id:flags.0?Peer reply_from:flags.5?MessageFwdHeader reply_media:flags.8?MessageMedia reply_to_top_id:flags.1?int quote_text:flags.6?string quote_entities:flags.7?Vector<MessageEntity> quote_offset:flags.10?int = MessageReplyHeader;
|
||||
messageReplyStoryHeader#9c98bfc1 user_id:long story_id:int = MessageReplyHeader;
|
||||
messageReplyStoryHeader#e5af939 peer:Peer story_id:int = MessageReplyHeader;
|
||||
messageReplies#83d60fc2 flags:# comments:flags.0?true replies:int replies_pts:int recent_repliers:flags.1?Vector<Peer> channel_id:flags.0?long max_id:flags.2?int read_max_id:flags.3?int = MessageReplies;
|
||||
peerBlocked#e8fd8014 peer_id:Peer date:int = PeerBlocked;
|
||||
stats.messageStats#7fe91c14 views_graph:StatsGraph reactions_by_emotion_graph:StatsGraph = stats.MessageStats;
|
||||
@ -1152,7 +1154,7 @@ sponsoredWebPage#3db8ec63 flags:# url:string site_name:string photo:flags.0?Phot
|
||||
storyViews#8d595cd6 flags:# has_viewers:flags.1?true views_count:int forwards_count:flags.2?int reactions:flags.3?Vector<ReactionCount> reactions_count:flags.4?int recent_viewers:flags.0?Vector<long> = StoryViews;
|
||||
storyItemDeleted#51e6ee4f id:int = StoryItem;
|
||||
storyItemSkipped#ffadc913 flags:# close_friends:flags.8?true id:int date:int expire_date:int = StoryItem;
|
||||
storyItem#af6365a1 flags:# pinned:flags.5?true public:flags.7?true close_friends:flags.8?true min:flags.9?true noforwards:flags.10?true edited:flags.11?true contacts:flags.12?true selected_contacts:flags.13?true out:flags.16?true id:int date:int fwd_from:flags.17?StoryFwdHeader expire_date:int caption:flags.0?string entities:flags.1?Vector<MessageEntity> media:MessageMedia media_areas:flags.14?Vector<MediaArea> privacy:flags.2?Vector<PrivacyRule> views:flags.3?StoryViews sent_reaction:flags.15?Reaction = StoryItem;
|
||||
storyItem#79b26a24 flags:# pinned:flags.5?true public:flags.7?true close_friends:flags.8?true min:flags.9?true noforwards:flags.10?true edited:flags.11?true contacts:flags.12?true selected_contacts:flags.13?true out:flags.16?true id:int date:int from_id:flags.18?Peer fwd_from:flags.17?StoryFwdHeader expire_date:int caption:flags.0?string entities:flags.1?Vector<MessageEntity> media:MessageMedia media_areas:flags.14?Vector<MediaArea> privacy:flags.2?Vector<PrivacyRule> views:flags.3?StoryViews sent_reaction:flags.15?Reaction = StoryItem;
|
||||
stories.allStoriesNotModified#1158fe3e flags:# state:string stealth_mode:StoriesStealthMode = stories.AllStories;
|
||||
stories.allStories#6efc5e81 flags:# has_more:flags.0?true count:int state:string peer_stories:Vector<PeerStories> chats:Vector<Chat> users:Vector<User> stealth_mode:StoriesStealthMode = stories.AllStories;
|
||||
stories.stories#5dd8c3c8 count:int stories:Vector<StoryItem> chats:Vector<Chat> users:Vector<User> = stories.Stories;
|
||||
@ -1162,7 +1164,7 @@ storyViewPublicRepost#bd74cf49 flags:# blocked:flags.0?true blocked_my_stories_f
|
||||
stories.storyViewsList#59d78fc5 flags:# count:int views_count:int forwards_count:int reactions_count:int views:Vector<StoryView> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryViewsList;
|
||||
stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews;
|
||||
inputReplyToMessage#22c0f6d5 flags:# reply_to_msg_id:int top_msg_id:flags.0?int reply_to_peer_id:flags.1?InputPeer quote_text:flags.2?string quote_entities:flags.3?Vector<MessageEntity> quote_offset:flags.4?int = InputReplyTo;
|
||||
inputReplyToStory#15b0f283 user_id:InputUser story_id:int = InputReplyTo;
|
||||
inputReplyToStory#5881323a peer:InputPeer story_id:int = InputReplyTo;
|
||||
exportedStoryLink#3fc9053b link:string = ExportedStoryLink;
|
||||
storiesStealthMode#712e27fd flags:# active_until_date:flags.0?int cooldown_until_date:flags.1?int = StoriesStealthMode;
|
||||
mediaAreaCoordinates#3d1ea4e x:double y:double w:double h:double rotation:double = MediaAreaCoordinates;
|
||||
@ -1195,7 +1197,7 @@ stats.publicForwards#93037e20 flags:# count:int forwards:Vector<PublicForward> n
|
||||
peerColor#b54b5acf flags:# color:flags.0?int background_emoji_id:flags.1?long = PeerColor;
|
||||
help.peerColorSet#26219a58 colors:Vector<int> = help.PeerColorSet;
|
||||
help.peerColorProfileSet#767d61eb palette_colors:Vector<int> bg_colors:Vector<int> story_colors:Vector<int> = help.PeerColorSet;
|
||||
help.peerColorOption#ef8430ab flags:# hidden:flags.0?true color_id:int colors:flags.1?help.PeerColorSet dark_colors:flags.2?help.PeerColorSet channel_min_level:flags.3?int = help.PeerColorOption;
|
||||
help.peerColorOption#adec6ebe flags:# hidden:flags.0?true color_id:int colors:flags.1?help.PeerColorSet dark_colors:flags.2?help.PeerColorSet channel_min_level:flags.3?int group_min_level:flags.4?int = help.PeerColorOption;
|
||||
help.peerColorsNotModified#2ba1f5ce = help.PeerColors;
|
||||
help.peerColors#f8ed08 hash:int colors:Vector<help.PeerColorOption> = help.PeerColors;
|
||||
storyReaction#6090d6d5 peer_id:Peer date:int reaction:Reaction = StoryReaction;
|
||||
@ -1538,6 +1540,7 @@ stories.getStoriesByID#5774ca74 peer:InputPeer id:Vector<int> = stories.Stories;
|
||||
stories.readStories#a556dac8 peer:InputPeer max_id:int = Vector<int>;
|
||||
stories.incrementStoryViews#b2028afb peer:InputPeer id:Vector<int> = Bool;
|
||||
stories.getStoryViewsList#7ed23c57 flags:# just_contacts:flags.0?true reactions_first:flags.2?true forwards_first:flags.3?true peer:InputPeer q:flags.1?string id:int offset:string limit:int = stories.StoryViewsList;
|
||||
stories.getStoriesViews#28e16cc8 peer:InputPeer id:Vector<int> = stories.StoryViews;
|
||||
stories.exportStoryLink#7b8def20 peer:InputPeer id:int = ExportedStoryLink;
|
||||
stories.report#1923fa8c peer:InputPeer id:Vector<int> reason:ReportReason message:string = Bool;
|
||||
stories.activateStealthMode#57bbd166 flags:# past:flags.0?true future:flags.1?true = Updates;
|
||||
|
||||
@ -331,6 +331,7 @@
|
||||
"stories.getPeerMaxIDs",
|
||||
"stories.togglePeerStoriesHidden",
|
||||
"stories.getPeerStories",
|
||||
"stories.getStoriesViews",
|
||||
"premium.getBoostsStatus",
|
||||
"premium.getBoostersList",
|
||||
"premium.applyBoost",
|
||||
|
||||
@ -101,7 +101,7 @@ channel#aadfc8f flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5
|
||||
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
|
||||
|
||||
chatFull#c9d31138 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions = ChatFull;
|
||||
channelFull#f2bcb6f flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper = ChatFull;
|
||||
channelFull#44c054a7 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet = ChatFull;
|
||||
|
||||
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
|
||||
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
|
||||
@ -114,7 +114,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
|
||||
chatPhoto#1c6e1c11 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = ChatPhoto;
|
||||
|
||||
messageEmpty#90a6ca84 flags:# id:int peer_id:flags.0?Peer = Message;
|
||||
message#76bec211 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true invert_media:flags.27?true id:int from_id:flags.8?Peer peer_id:Peer saved_peer_id:flags.28?Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector<RestrictionReason> ttl_period:flags.25?int = Message;
|
||||
message#1e4c8a69 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true invert_media:flags.27?true id:int from_id:flags.8?Peer from_boosts_applied:flags.29?int peer_id:Peer saved_peer_id:flags.28?Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector<RestrictionReason> ttl_period:flags.25?int = Message;
|
||||
messageService#2b085862 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?Peer peer_id:Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction ttl_period:flags.25?int = Message;
|
||||
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
@ -175,6 +175,7 @@ messageActionSetChatWallPaper#5060a3f4 flags:# same:flags.0?true for_both:flags.
|
||||
messageActionGiftCode#678c2e09 flags:# via_giveaway:flags.0?true unclaimed:flags.2?true boost_peer:flags.1?Peer months:int slug:string currency:flags.2?string amount:flags.2?long crypto_currency:flags.3?string crypto_amount:flags.3?long = MessageAction;
|
||||
messageActionGiveawayLaunch#332ba9ed = MessageAction;
|
||||
messageActionGiveawayResults#2a9fadc5 winners_count:int unclaimed_count:int = MessageAction;
|
||||
messageActionBoostApply#cc02aa6d boosts:int = MessageAction;
|
||||
|
||||
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||
@ -980,6 +981,7 @@ channelAdminLogEventActionChangePeerColor#5796e780 prev_value:PeerColor new_valu
|
||||
channelAdminLogEventActionChangeProfilePeerColor#5e477b25 prev_value:PeerColor new_value:PeerColor = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeWallpaper#31bb5d52 prev_value:WallPaper new_value:WallPaper = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeEmojiStatus#3ea9feb1 prev_value:EmojiStatus new_value:EmojiStatus = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeEmojiStickerSet#46d840ab prev_stickerset:InputStickerSet new_stickerset:InputStickerSet = ChannelAdminLogEventAction;
|
||||
|
||||
channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
|
||||
|
||||
@ -1275,7 +1277,7 @@ messages.messageViews#b6c4f543 views:Vector<MessageViews> chats:Vector<Chat> use
|
||||
messages.discussionMessage#a6341782 flags:# messages:Vector<Message> max_id:flags.0?int read_inbox_max_id:flags.1?int read_outbox_max_id:flags.2?int unread_count:int chats:Vector<Chat> users:Vector<User> = messages.DiscussionMessage;
|
||||
|
||||
messageReplyHeader#afbc09db flags:# reply_to_scheduled:flags.2?true forum_topic:flags.3?true quote:flags.9?true reply_to_msg_id:flags.4?int reply_to_peer_id:flags.0?Peer reply_from:flags.5?MessageFwdHeader reply_media:flags.8?MessageMedia reply_to_top_id:flags.1?int quote_text:flags.6?string quote_entities:flags.7?Vector<MessageEntity> quote_offset:flags.10?int = MessageReplyHeader;
|
||||
messageReplyStoryHeader#9c98bfc1 user_id:long story_id:int = MessageReplyHeader;
|
||||
messageReplyStoryHeader#e5af939 peer:Peer story_id:int = MessageReplyHeader;
|
||||
|
||||
messageReplies#83d60fc2 flags:# comments:flags.0?true replies:int replies_pts:int recent_repliers:flags.1?Vector<Peer> channel_id:flags.0?long max_id:flags.2?int read_max_id:flags.3?int = MessageReplies;
|
||||
|
||||
@ -1554,7 +1556,7 @@ storyViews#8d595cd6 flags:# has_viewers:flags.1?true views_count:int forwards_co
|
||||
|
||||
storyItemDeleted#51e6ee4f id:int = StoryItem;
|
||||
storyItemSkipped#ffadc913 flags:# close_friends:flags.8?true id:int date:int expire_date:int = StoryItem;
|
||||
storyItem#af6365a1 flags:# pinned:flags.5?true public:flags.7?true close_friends:flags.8?true min:flags.9?true noforwards:flags.10?true edited:flags.11?true contacts:flags.12?true selected_contacts:flags.13?true out:flags.16?true id:int date:int fwd_from:flags.17?StoryFwdHeader expire_date:int caption:flags.0?string entities:flags.1?Vector<MessageEntity> media:MessageMedia media_areas:flags.14?Vector<MediaArea> privacy:flags.2?Vector<PrivacyRule> views:flags.3?StoryViews sent_reaction:flags.15?Reaction = StoryItem;
|
||||
storyItem#79b26a24 flags:# pinned:flags.5?true public:flags.7?true close_friends:flags.8?true min:flags.9?true noforwards:flags.10?true edited:flags.11?true contacts:flags.12?true selected_contacts:flags.13?true out:flags.16?true id:int date:int from_id:flags.18?Peer fwd_from:flags.17?StoryFwdHeader expire_date:int caption:flags.0?string entities:flags.1?Vector<MessageEntity> media:MessageMedia media_areas:flags.14?Vector<MediaArea> privacy:flags.2?Vector<PrivacyRule> views:flags.3?StoryViews sent_reaction:flags.15?Reaction = StoryItem;
|
||||
|
||||
stories.allStoriesNotModified#1158fe3e flags:# state:string stealth_mode:StoriesStealthMode = stories.AllStories;
|
||||
stories.allStories#6efc5e81 flags:# has_more:flags.0?true count:int state:string peer_stories:Vector<PeerStories> chats:Vector<Chat> users:Vector<User> stealth_mode:StoriesStealthMode = stories.AllStories;
|
||||
@ -1570,7 +1572,7 @@ stories.storyViewsList#59d78fc5 flags:# count:int views_count:int forwards_count
|
||||
stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews;
|
||||
|
||||
inputReplyToMessage#22c0f6d5 flags:# reply_to_msg_id:int top_msg_id:flags.0?int reply_to_peer_id:flags.1?InputPeer quote_text:flags.2?string quote_entities:flags.3?Vector<MessageEntity> quote_offset:flags.4?int = InputReplyTo;
|
||||
inputReplyToStory#15b0f283 user_id:InputUser story_id:int = InputReplyTo;
|
||||
inputReplyToStory#5881323a peer:InputPeer story_id:int = InputReplyTo;
|
||||
|
||||
exportedStoryLink#3fc9053b link:string = ExportedStoryLink;
|
||||
|
||||
@ -1627,7 +1629,7 @@ peerColor#b54b5acf flags:# color:flags.0?int background_emoji_id:flags.1?long =
|
||||
help.peerColorSet#26219a58 colors:Vector<int> = help.PeerColorSet;
|
||||
help.peerColorProfileSet#767d61eb palette_colors:Vector<int> bg_colors:Vector<int> story_colors:Vector<int> = help.PeerColorSet;
|
||||
|
||||
help.peerColorOption#ef8430ab flags:# hidden:flags.0?true color_id:int colors:flags.1?help.PeerColorSet dark_colors:flags.2?help.PeerColorSet channel_min_level:flags.3?int = help.PeerColorOption;
|
||||
help.peerColorOption#adec6ebe flags:# hidden:flags.0?true color_id:int colors:flags.1?help.PeerColorSet dark_colors:flags.2?help.PeerColorSet channel_min_level:flags.3?int group_min_level:flags.4?int = help.PeerColorOption;
|
||||
|
||||
help.peerColorsNotModified#2ba1f5ce = help.PeerColors;
|
||||
help.peerColors#f8ed08 hash:int colors:Vector<help.PeerColorOption> = help.PeerColors;
|
||||
@ -2111,6 +2113,8 @@ channels.updateColor#d8aa3671 flags:# for_profile:flags.1?true channel:InputChan
|
||||
channels.toggleViewForumAsMessages#9738bb15 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.getChannelRecommendations#83b70d97 channel:InputChannel = messages.Chats;
|
||||
channels.updateEmojiStatus#f0d3e6a8 channel:InputChannel emoji_status:EmojiStatus = Updates;
|
||||
channels.setBoostsToUnblockRestrictions#ad399cee channel:InputChannel boosts:int = Updates;
|
||||
channels.setEmojiStickers#3cd930b7 channel:InputChannel stickerset:InputStickerSet = Bool;
|
||||
|
||||
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
|
||||
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
|
||||
|
||||
@ -53,212 +53,214 @@ $icons-map: (
|
||||
"avatar-deleted-account": "\f116",
|
||||
"avatar-saved-messages": "\f117",
|
||||
"bold": "\f118",
|
||||
"boost": "\f119",
|
||||
"boostcircle": "\f11a",
|
||||
"bot-command": "\f11b",
|
||||
"bot-commands-filled": "\f11c",
|
||||
"bots": "\f11d",
|
||||
"bug": "\f11e",
|
||||
"calendar-filter": "\f11f",
|
||||
"calendar": "\f120",
|
||||
"camera-add": "\f121",
|
||||
"camera": "\f122",
|
||||
"car": "\f123",
|
||||
"card": "\f124",
|
||||
"channel-filled": "\f125",
|
||||
"channel": "\f126",
|
||||
"channelviews": "\f127",
|
||||
"chat-badge": "\f128",
|
||||
"chats-badge": "\f129",
|
||||
"check": "\f12a",
|
||||
"close-circle": "\f12b",
|
||||
"close-topic": "\f12c",
|
||||
"close": "\f12d",
|
||||
"cloud-download": "\f12e",
|
||||
"collapse": "\f12f",
|
||||
"colorize": "\f130",
|
||||
"comments-sticker": "\f131",
|
||||
"comments": "\f132",
|
||||
"copy-media": "\f133",
|
||||
"copy": "\f134",
|
||||
"darkmode": "\f135",
|
||||
"data": "\f136",
|
||||
"delete-filled": "\f137",
|
||||
"delete-left": "\f138",
|
||||
"delete-user": "\f139",
|
||||
"delete": "\f13a",
|
||||
"document": "\f13b",
|
||||
"double-badge": "\f13c",
|
||||
"down": "\f13d",
|
||||
"download": "\f13e",
|
||||
"eats": "\f13f",
|
||||
"edit": "\f140",
|
||||
"email": "\f141",
|
||||
"enter": "\f142",
|
||||
"expand": "\f143",
|
||||
"eye-closed-outline": "\f144",
|
||||
"eye-closed": "\f145",
|
||||
"eye-outline": "\f146",
|
||||
"eye": "\f147",
|
||||
"favorite-filled": "\f148",
|
||||
"favorite": "\f149",
|
||||
"file-badge": "\f14a",
|
||||
"flag": "\f14b",
|
||||
"folder-badge": "\f14c",
|
||||
"folder": "\f14d",
|
||||
"fontsize": "\f14e",
|
||||
"forums": "\f14f",
|
||||
"forward": "\f150",
|
||||
"fullscreen": "\f151",
|
||||
"gifs": "\f152",
|
||||
"gift": "\f153",
|
||||
"group-filled": "\f154",
|
||||
"group": "\f155",
|
||||
"grouped-disable": "\f156",
|
||||
"grouped": "\f157",
|
||||
"hand-stop": "\f158",
|
||||
"hashtag": "\f159",
|
||||
"heart-outline": "\f15a",
|
||||
"heart": "\f15b",
|
||||
"help": "\f15c",
|
||||
"info-filled": "\f15d",
|
||||
"info": "\f15e",
|
||||
"install": "\f15f",
|
||||
"italic": "\f160",
|
||||
"key": "\f161",
|
||||
"keyboard": "\f162",
|
||||
"lamp": "\f163",
|
||||
"language": "\f164",
|
||||
"large-pause": "\f165",
|
||||
"large-play": "\f166",
|
||||
"link-badge": "\f167",
|
||||
"link-broken": "\f168",
|
||||
"link": "\f169",
|
||||
"location": "\f16a",
|
||||
"lock-badge": "\f16b",
|
||||
"lock": "\f16c",
|
||||
"logout": "\f16d",
|
||||
"loop": "\f16e",
|
||||
"mention": "\f16f",
|
||||
"message-failed": "\f170",
|
||||
"message-pending": "\f171",
|
||||
"message-read": "\f172",
|
||||
"message-succeeded": "\f173",
|
||||
"message": "\f174",
|
||||
"microphone-alt": "\f175",
|
||||
"microphone": "\f176",
|
||||
"monospace": "\f177",
|
||||
"more-circle": "\f178",
|
||||
"more": "\f179",
|
||||
"mute": "\f17a",
|
||||
"muted": "\f17b",
|
||||
"my-notes": "\f17c",
|
||||
"new-chat-filled": "\f17d",
|
||||
"next": "\f17e",
|
||||
"noise-suppression": "\f17f",
|
||||
"non-contacts": "\f180",
|
||||
"one-filled": "\f181",
|
||||
"open-in-new-tab": "\f182",
|
||||
"password-off": "\f183",
|
||||
"pause": "\f184",
|
||||
"permissions": "\f185",
|
||||
"phone-discard-outline": "\f186",
|
||||
"phone-discard": "\f187",
|
||||
"phone": "\f188",
|
||||
"photo": "\f189",
|
||||
"pin-badge": "\f18a",
|
||||
"pin-list": "\f18b",
|
||||
"pin": "\f18c",
|
||||
"pinned-chat": "\f18d",
|
||||
"pinned-message": "\f18e",
|
||||
"pip": "\f18f",
|
||||
"play-story": "\f190",
|
||||
"play": "\f191",
|
||||
"poll": "\f192",
|
||||
"premium": "\f193",
|
||||
"previous": "\f194",
|
||||
"privacy-policy": "\f195",
|
||||
"quote-text": "\f196",
|
||||
"quote": "\f197",
|
||||
"readchats": "\f198",
|
||||
"recent": "\f199",
|
||||
"reload": "\f19a",
|
||||
"remove": "\f19b",
|
||||
"reopen-topic": "\f19c",
|
||||
"replace": "\f19d",
|
||||
"replies": "\f19e",
|
||||
"reply-filled": "\f19f",
|
||||
"reply": "\f1a0",
|
||||
"revote": "\f1a1",
|
||||
"save-story": "\f1a2",
|
||||
"saved-messages": "\f1a3",
|
||||
"schedule": "\f1a4",
|
||||
"search": "\f1a5",
|
||||
"select": "\f1a6",
|
||||
"send-outline": "\f1a7",
|
||||
"send": "\f1a8",
|
||||
"settings-filled": "\f1a9",
|
||||
"settings": "\f1aa",
|
||||
"share-filled": "\f1ab",
|
||||
"share-screen-outlined": "\f1ac",
|
||||
"share-screen-stop": "\f1ad",
|
||||
"share-screen": "\f1ae",
|
||||
"sidebar": "\f1af",
|
||||
"skip-next": "\f1b0",
|
||||
"skip-previous": "\f1b1",
|
||||
"smallscreen": "\f1b2",
|
||||
"smile": "\f1b3",
|
||||
"sort": "\f1b4",
|
||||
"speaker-muted-story": "\f1b5",
|
||||
"speaker-outline": "\f1b6",
|
||||
"speaker-story": "\f1b7",
|
||||
"speaker": "\f1b8",
|
||||
"spoiler-disable": "\f1b9",
|
||||
"spoiler": "\f1ba",
|
||||
"sport": "\f1bb",
|
||||
"stats": "\f1bc",
|
||||
"stealth-future": "\f1bd",
|
||||
"stealth-past": "\f1be",
|
||||
"stickers": "\f1bf",
|
||||
"stop-raising-hand": "\f1c0",
|
||||
"stop": "\f1c1",
|
||||
"story-caption": "\f1c2",
|
||||
"story-expired": "\f1c3",
|
||||
"story-priority": "\f1c4",
|
||||
"story-reply": "\f1c5",
|
||||
"strikethrough": "\f1c6",
|
||||
"tag-add": "\f1c7",
|
||||
"tag-crossed": "\f1c8",
|
||||
"tag-filter": "\f1c9",
|
||||
"tag-name": "\f1ca",
|
||||
"tag": "\f1cb",
|
||||
"timer": "\f1cc",
|
||||
"transcribe": "\f1cd",
|
||||
"truck": "\f1ce",
|
||||
"unarchive": "\f1cf",
|
||||
"underlined": "\f1d0",
|
||||
"unlock-badge": "\f1d1",
|
||||
"unlock": "\f1d2",
|
||||
"unmute": "\f1d3",
|
||||
"unpin": "\f1d4",
|
||||
"unread": "\f1d5",
|
||||
"up": "\f1d6",
|
||||
"user-filled": "\f1d7",
|
||||
"user-online": "\f1d8",
|
||||
"user": "\f1d9",
|
||||
"video-outlined": "\f1da",
|
||||
"video-stop": "\f1db",
|
||||
"video": "\f1dc",
|
||||
"view-once": "\f1dd",
|
||||
"voice-chat": "\f1de",
|
||||
"volume-1": "\f1df",
|
||||
"volume-2": "\f1e0",
|
||||
"volume-3": "\f1e1",
|
||||
"web": "\f1e2",
|
||||
"webapp": "\f1e3",
|
||||
"word-wrap": "\f1e4",
|
||||
"zoom-in": "\f1e5",
|
||||
"zoom-out": "\f1e6",
|
||||
"boost-outline": "\f119",
|
||||
"boost": "\f11a",
|
||||
"boostcircle": "\f11b",
|
||||
"boosts": "\f11c",
|
||||
"bot-command": "\f11d",
|
||||
"bot-commands-filled": "\f11e",
|
||||
"bots": "\f11f",
|
||||
"bug": "\f120",
|
||||
"calendar-filter": "\f121",
|
||||
"calendar": "\f122",
|
||||
"camera-add": "\f123",
|
||||
"camera": "\f124",
|
||||
"car": "\f125",
|
||||
"card": "\f126",
|
||||
"channel-filled": "\f127",
|
||||
"channel": "\f128",
|
||||
"channelviews": "\f129",
|
||||
"chat-badge": "\f12a",
|
||||
"chats-badge": "\f12b",
|
||||
"check": "\f12c",
|
||||
"close-circle": "\f12d",
|
||||
"close-topic": "\f12e",
|
||||
"close": "\f12f",
|
||||
"cloud-download": "\f130",
|
||||
"collapse": "\f131",
|
||||
"colorize": "\f132",
|
||||
"comments-sticker": "\f133",
|
||||
"comments": "\f134",
|
||||
"copy-media": "\f135",
|
||||
"copy": "\f136",
|
||||
"darkmode": "\f137",
|
||||
"data": "\f138",
|
||||
"delete-filled": "\f139",
|
||||
"delete-left": "\f13a",
|
||||
"delete-user": "\f13b",
|
||||
"delete": "\f13c",
|
||||
"document": "\f13d",
|
||||
"double-badge": "\f13e",
|
||||
"down": "\f13f",
|
||||
"download": "\f140",
|
||||
"eats": "\f141",
|
||||
"edit": "\f142",
|
||||
"email": "\f143",
|
||||
"enter": "\f144",
|
||||
"expand": "\f145",
|
||||
"eye-closed-outline": "\f146",
|
||||
"eye-closed": "\f147",
|
||||
"eye-outline": "\f148",
|
||||
"eye": "\f149",
|
||||
"favorite-filled": "\f14a",
|
||||
"favorite": "\f14b",
|
||||
"file-badge": "\f14c",
|
||||
"flag": "\f14d",
|
||||
"folder-badge": "\f14e",
|
||||
"folder": "\f14f",
|
||||
"fontsize": "\f150",
|
||||
"forums": "\f151",
|
||||
"forward": "\f152",
|
||||
"fullscreen": "\f153",
|
||||
"gifs": "\f154",
|
||||
"gift": "\f155",
|
||||
"group-filled": "\f156",
|
||||
"group": "\f157",
|
||||
"grouped-disable": "\f158",
|
||||
"grouped": "\f159",
|
||||
"hand-stop": "\f15a",
|
||||
"hashtag": "\f15b",
|
||||
"heart-outline": "\f15c",
|
||||
"heart": "\f15d",
|
||||
"help": "\f15e",
|
||||
"info-filled": "\f15f",
|
||||
"info": "\f160",
|
||||
"install": "\f161",
|
||||
"italic": "\f162",
|
||||
"key": "\f163",
|
||||
"keyboard": "\f164",
|
||||
"lamp": "\f165",
|
||||
"language": "\f166",
|
||||
"large-pause": "\f167",
|
||||
"large-play": "\f168",
|
||||
"link-badge": "\f169",
|
||||
"link-broken": "\f16a",
|
||||
"link": "\f16b",
|
||||
"location": "\f16c",
|
||||
"lock-badge": "\f16d",
|
||||
"lock": "\f16e",
|
||||
"logout": "\f16f",
|
||||
"loop": "\f170",
|
||||
"mention": "\f171",
|
||||
"message-failed": "\f172",
|
||||
"message-pending": "\f173",
|
||||
"message-read": "\f174",
|
||||
"message-succeeded": "\f175",
|
||||
"message": "\f176",
|
||||
"microphone-alt": "\f177",
|
||||
"microphone": "\f178",
|
||||
"monospace": "\f179",
|
||||
"more-circle": "\f17a",
|
||||
"more": "\f17b",
|
||||
"mute": "\f17c",
|
||||
"muted": "\f17d",
|
||||
"my-notes": "\f17e",
|
||||
"new-chat-filled": "\f17f",
|
||||
"next": "\f180",
|
||||
"noise-suppression": "\f181",
|
||||
"non-contacts": "\f182",
|
||||
"one-filled": "\f183",
|
||||
"open-in-new-tab": "\f184",
|
||||
"password-off": "\f185",
|
||||
"pause": "\f186",
|
||||
"permissions": "\f187",
|
||||
"phone-discard-outline": "\f188",
|
||||
"phone-discard": "\f189",
|
||||
"phone": "\f18a",
|
||||
"photo": "\f18b",
|
||||
"pin-badge": "\f18c",
|
||||
"pin-list": "\f18d",
|
||||
"pin": "\f18e",
|
||||
"pinned-chat": "\f18f",
|
||||
"pinned-message": "\f190",
|
||||
"pip": "\f191",
|
||||
"play-story": "\f192",
|
||||
"play": "\f193",
|
||||
"poll": "\f194",
|
||||
"premium": "\f195",
|
||||
"previous": "\f196",
|
||||
"privacy-policy": "\f197",
|
||||
"quote-text": "\f198",
|
||||
"quote": "\f199",
|
||||
"readchats": "\f19a",
|
||||
"recent": "\f19b",
|
||||
"reload": "\f19c",
|
||||
"remove": "\f19d",
|
||||
"reopen-topic": "\f19e",
|
||||
"replace": "\f19f",
|
||||
"replies": "\f1a0",
|
||||
"reply-filled": "\f1a1",
|
||||
"reply": "\f1a2",
|
||||
"revote": "\f1a3",
|
||||
"save-story": "\f1a4",
|
||||
"saved-messages": "\f1a5",
|
||||
"schedule": "\f1a6",
|
||||
"search": "\f1a7",
|
||||
"select": "\f1a8",
|
||||
"send-outline": "\f1a9",
|
||||
"send": "\f1aa",
|
||||
"settings-filled": "\f1ab",
|
||||
"settings": "\f1ac",
|
||||
"share-filled": "\f1ad",
|
||||
"share-screen-outlined": "\f1ae",
|
||||
"share-screen-stop": "\f1af",
|
||||
"share-screen": "\f1b0",
|
||||
"sidebar": "\f1b1",
|
||||
"skip-next": "\f1b2",
|
||||
"skip-previous": "\f1b3",
|
||||
"smallscreen": "\f1b4",
|
||||
"smile": "\f1b5",
|
||||
"sort": "\f1b6",
|
||||
"speaker-muted-story": "\f1b7",
|
||||
"speaker-outline": "\f1b8",
|
||||
"speaker-story": "\f1b9",
|
||||
"speaker": "\f1ba",
|
||||
"spoiler-disable": "\f1bb",
|
||||
"spoiler": "\f1bc",
|
||||
"sport": "\f1bd",
|
||||
"stats": "\f1be",
|
||||
"stealth-future": "\f1bf",
|
||||
"stealth-past": "\f1c0",
|
||||
"stickers": "\f1c1",
|
||||
"stop-raising-hand": "\f1c2",
|
||||
"stop": "\f1c3",
|
||||
"story-caption": "\f1c4",
|
||||
"story-expired": "\f1c5",
|
||||
"story-priority": "\f1c6",
|
||||
"story-reply": "\f1c7",
|
||||
"strikethrough": "\f1c8",
|
||||
"tag-add": "\f1c9",
|
||||
"tag-crossed": "\f1ca",
|
||||
"tag-filter": "\f1cb",
|
||||
"tag-name": "\f1cc",
|
||||
"tag": "\f1cd",
|
||||
"timer": "\f1ce",
|
||||
"transcribe": "\f1cf",
|
||||
"truck": "\f1d0",
|
||||
"unarchive": "\f1d1",
|
||||
"underlined": "\f1d2",
|
||||
"unlock-badge": "\f1d3",
|
||||
"unlock": "\f1d4",
|
||||
"unmute": "\f1d5",
|
||||
"unpin": "\f1d6",
|
||||
"unread": "\f1d7",
|
||||
"up": "\f1d8",
|
||||
"user-filled": "\f1d9",
|
||||
"user-online": "\f1da",
|
||||
"user": "\f1db",
|
||||
"video-outlined": "\f1dc",
|
||||
"video-stop": "\f1dd",
|
||||
"video": "\f1de",
|
||||
"view-once": "\f1df",
|
||||
"voice-chat": "\f1e0",
|
||||
"volume-1": "\f1e1",
|
||||
"volume-2": "\f1e2",
|
||||
"volume-3": "\f1e3",
|
||||
"web": "\f1e4",
|
||||
"webapp": "\f1e5",
|
||||
"word-wrap": "\f1e6",
|
||||
"zoom-in": "\f1e7",
|
||||
"zoom-out": "\f1e8",
|
||||
);
|
||||
|
||||
.icon-active-sessions::before {
|
||||
@ -333,12 +335,18 @@ $icons-map: (
|
||||
.icon-bold::before {
|
||||
content: map.get($icons-map, "bold");
|
||||
}
|
||||
.icon-boost-outline::before {
|
||||
content: map.get($icons-map, "boost-outline");
|
||||
}
|
||||
.icon-boost::before {
|
||||
content: map.get($icons-map, "boost");
|
||||
}
|
||||
.icon-boostcircle::before {
|
||||
content: map.get($icons-map, "boostcircle");
|
||||
}
|
||||
.icon-boosts::before {
|
||||
content: map.get($icons-map, "boosts");
|
||||
}
|
||||
.icon-bot-command::before {
|
||||
content: map.get($icons-map, "bot-command");
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -23,8 +23,10 @@ export type FontIconName =
|
||||
| 'avatar-deleted-account'
|
||||
| 'avatar-saved-messages'
|
||||
| 'bold'
|
||||
| 'boost-outline'
|
||||
| 'boost'
|
||||
| 'boostcircle'
|
||||
| 'boosts'
|
||||
| 'bot-command'
|
||||
| 'bot-commands-filled'
|
||||
| 'bots'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user