Support Channel direct messages (#5990)
This commit is contained in:
parent
8f9310c7d5
commit
a85fec6c65
@ -98,6 +98,7 @@ export interface GramJsAppConfig extends LimitsConfig {
|
|||||||
stars_stargift_resale_amount_max?: number;
|
stars_stargift_resale_amount_max?: number;
|
||||||
stars_stargift_resale_amount_min?: number;
|
stars_stargift_resale_amount_min?: number;
|
||||||
stars_stargift_resale_commission_permille?: number;
|
stars_stargift_resale_commission_permille?: number;
|
||||||
|
poll_answers_max?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildEmojiSounds(appConfig: GramJsAppConfig) {
|
function buildEmojiSounds(appConfig: GramJsAppConfig) {
|
||||||
@ -198,5 +199,6 @@ export function buildAppConfig(json: GramJs.TypeJSONValue, hash: number): ApiApp
|
|||||||
starsStargiftResaleAmountMin: appConfig.stars_stargift_resale_amount_min,
|
starsStargiftResaleAmountMin: appConfig.stars_stargift_resale_amount_min,
|
||||||
starsStargiftResaleAmountMax: appConfig.stars_stargift_resale_amount_max,
|
starsStargiftResaleAmountMax: appConfig.stars_stargift_resale_amount_max,
|
||||||
starsStargiftResaleCommissionPermille: appConfig.stars_stargift_resale_commission_permille,
|
starsStargiftResaleCommissionPermille: appConfig.stars_stargift_resale_commission_permille,
|
||||||
|
pollMaxAnswers: appConfig.poll_answers_max,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -110,6 +110,9 @@ function buildApiChatFieldsFromPeerEntity(
|
|||||||
isJoinToSend: channel?.joinToSend,
|
isJoinToSend: channel?.joinToSend,
|
||||||
isJoinRequest: channel?.joinRequest,
|
isJoinRequest: channel?.joinRequest,
|
||||||
isForum: channel?.forum,
|
isForum: channel?.forum,
|
||||||
|
isMonoforum: channel?.monoforum,
|
||||||
|
linkedMonoforumId: channel?.linkedMonoforumId && buildApiPeerId(channel.linkedMonoforumId, 'channel'),
|
||||||
|
areChannelMessagesAllowed: channel?.broadcastMessagesAllowed,
|
||||||
areStoriesHidden,
|
areStoriesHidden,
|
||||||
maxStoryId,
|
maxStoryId,
|
||||||
hasStories: Boolean(maxStoryId) && !storiesUnavailable,
|
hasStories: Boolean(maxStoryId) && !storiesUnavailable,
|
||||||
|
|||||||
@ -426,11 +426,12 @@ export function buildApiMessageAction(action: GramJs.TypeMessageAction): ApiMess
|
|||||||
}
|
}
|
||||||
if (action instanceof GramJs.MessageActionPaidMessagesPrice) {
|
if (action instanceof GramJs.MessageActionPaidMessagesPrice) {
|
||||||
const {
|
const {
|
||||||
stars,
|
stars, broadcastMessagesAllowed,
|
||||||
} = action;
|
} = action;
|
||||||
return {
|
return {
|
||||||
mediaType: 'action',
|
mediaType: 'action',
|
||||||
type: 'paidMessagesPrice',
|
type: 'paidMessagesPrice',
|
||||||
|
isAllowedInChannel: broadcastMessagesAllowed,
|
||||||
stars: stars.toJSNumber(),
|
stars: stars.toJSNumber(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -287,6 +287,7 @@ export function buildMessageDraft(draft: GramJs.TypeDraftMessage): ApiDraft | un
|
|||||||
replyToMsgId: replyTo.replyToMsgId,
|
replyToMsgId: replyTo.replyToMsgId,
|
||||||
replyToTopId: replyTo.topMsgId,
|
replyToTopId: replyTo.topMsgId,
|
||||||
replyToPeerId: replyTo.replyToPeerId && getApiChatIdFromMtpPeer(replyTo.replyToPeerId),
|
replyToPeerId: replyTo.replyToPeerId && getApiChatIdFromMtpPeer(replyTo.replyToPeerId),
|
||||||
|
monoforumPeerId: replyTo.monoforumPeerId && getApiChatIdFromMtpPeer(replyTo.monoforumPeerId),
|
||||||
quoteText: replyTo.quoteText ? buildMessageTextContent(replyTo.quoteText, replyTo.quoteEntities) : undefined,
|
quoteText: replyTo.quoteText ? buildMessageTextContent(replyTo.quoteText, replyTo.quoteEntities) : undefined,
|
||||||
quoteOffset: replyTo.quoteOffset,
|
quoteOffset: replyTo.quoteOffset,
|
||||||
} satisfies ApiInputMessageReplyInfo : undefined;
|
} satisfies ApiInputMessageReplyInfo : undefined;
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { Api as GramJs } from '../../../lib/gramjs';
|
|||||||
|
|
||||||
import type { ApiEmojiStatusType, ApiPeerColor } from '../../types';
|
import type { ApiEmojiStatusType, ApiPeerColor } from '../../types';
|
||||||
|
|
||||||
import { CHANNEL_ID_LENGTH } from '../../../config';
|
import { CHANNEL_ID_BASE } from '../../../config';
|
||||||
import { numberToHexColor } from '../../../util/colors';
|
import { numberToHexColor } from '../../../util/colors';
|
||||||
|
|
||||||
type TypePeerOrInput = GramJs.TypePeer | GramJs.TypeInputPeer | GramJs.TypeInputUser | GramJs.TypeInputChannel;
|
type TypePeerOrInput = GramJs.TypePeer | GramJs.TypeInputPeer | GramJs.TypeInputUser | GramJs.TypeInputChannel;
|
||||||
@ -26,13 +26,10 @@ export function buildApiPeerId(id: BigInt.BigInteger, type: 'user' | 'chat' | 'c
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'channel') {
|
if (type === 'channel') {
|
||||||
// Simulates TDLib https://github.com/tdlib/td/blob/d7203eb719304866a7eb7033ef03d421459335b8/td/telegram/DialogId.cpp#L54
|
return id.add(CHANNEL_ID_BASE).negate().toString();
|
||||||
// But using only string operations. Should be fine until channel ids reach 10^12
|
|
||||||
// Example: 12345678 -> -1000012345678
|
|
||||||
return `-1${id.toString().padStart(CHANNEL_ID_LENGTH - 2, '0')}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return `-${id.toString()}`;
|
return id.negate().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getApiChatIdFromMtpPeer(peer: TypePeerOrInput) {
|
export function getApiChatIdFromMtpPeer(peer: TypePeerOrInput) {
|
||||||
|
|||||||
@ -37,23 +37,22 @@ import {
|
|||||||
ApiMessageEntityTypes,
|
ApiMessageEntityTypes,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
|
|
||||||
import { CHANNEL_ID_LENGTH, DEFAULT_STATUS_ICON_ID } from '../../../config';
|
import { CHANNEL_ID_BASE, DEFAULT_STATUS_ICON_ID } from '../../../config';
|
||||||
import { pick } from '../../../util/iteratees';
|
import { pick } from '../../../util/iteratees';
|
||||||
import { deserializeBytes } from '../helpers/misc';
|
import { deserializeBytes } from '../helpers/misc';
|
||||||
import localDb from '../localDb';
|
import localDb from '../localDb';
|
||||||
|
|
||||||
function checkIfChannelId(id: string) {
|
export function getEntityTypeById(peerId: string) {
|
||||||
return id.length === CHANNEL_ID_LENGTH && id.startsWith('-1');
|
const n = Number(peerId);
|
||||||
}
|
if (n > 0) {
|
||||||
|
|
||||||
export function getEntityTypeById(chatOrUserId: string) {
|
|
||||||
if (!chatOrUserId.startsWith('-')) {
|
|
||||||
return 'user';
|
return 'user';
|
||||||
} else if (checkIfChannelId(chatOrUserId)) {
|
|
||||||
return 'channel';
|
|
||||||
} else {
|
|
||||||
return 'chat';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (n < -CHANNEL_ID_BASE) {
|
||||||
|
return 'channel';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'chat';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildPeer(chatOrUserId: string): GramJs.TypePeer {
|
export function buildPeer(chatOrUserId: string): GramJs.TypePeer {
|
||||||
@ -569,11 +568,13 @@ export function buildMtpPeerId(id: string, type: 'user' | 'chat' | 'channel') {
|
|||||||
return BigInt(id);
|
return BigInt(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const n = Number(id);
|
||||||
|
|
||||||
if (type === 'channel') {
|
if (type === 'channel') {
|
||||||
return BigInt(id.slice(2)); // Slice "-1", zeroes are trimmed when converting to BigInt
|
return BigInt(-n - CHANNEL_ID_BASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return BigInt(id.slice(1));
|
return BigInt(n * -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildInputGroupCall(groupCall: Partial<ApiGroupCall>) {
|
export function buildInputGroupCall(groupCall: Partial<ApiGroupCall>) {
|
||||||
@ -843,12 +844,13 @@ export function buildInputReplyTo(replyInfo: ApiInputReplyInfo) {
|
|||||||
|
|
||||||
if (replyInfo.type === 'message') {
|
if (replyInfo.type === 'message') {
|
||||||
const {
|
const {
|
||||||
replyToMsgId, replyToTopId, replyToPeerId, quoteText, quoteOffset,
|
replyToMsgId, replyToTopId, replyToPeerId, quoteText, quoteOffset, monoforumPeerId,
|
||||||
} = replyInfo;
|
} = replyInfo;
|
||||||
return new GramJs.InputReplyToMessage({
|
return new GramJs.InputReplyToMessage({
|
||||||
replyToMsgId,
|
replyToMsgId,
|
||||||
topMsgId: replyToTopId,
|
topMsgId: replyToTopId,
|
||||||
replyToPeerId: replyToPeerId ? buildInputPeerFromLocalDb(replyToPeerId)! : undefined,
|
replyToPeerId: replyToPeerId ? buildInputPeerFromLocalDb(replyToPeerId)! : undefined,
|
||||||
|
monoforumPeerId: monoforumPeerId ? buildInputPeerFromLocalDb(monoforumPeerId)! : undefined,
|
||||||
quoteText: quoteText?.text,
|
quoteText: quoteText?.text,
|
||||||
quoteEntities: quoteText?.entities?.map(buildMtpMessageEntity),
|
quoteEntities: quoteText?.entities?.map(buildMtpMessageEntity),
|
||||||
quoteOffset,
|
quoteOffset,
|
||||||
|
|||||||
@ -299,6 +299,10 @@ export async function fetchSavedChats({
|
|||||||
const chats: ApiChat[] = [];
|
const chats: ApiChat[] = [];
|
||||||
|
|
||||||
dialogs.forEach((dialog) => {
|
dialogs.forEach((dialog) => {
|
||||||
|
if (dialog instanceof GramJs.MonoForumDialog) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const peerEntity = peersByKey[getPeerKey(dialog.peer)];
|
const peerEntity = peersByKey[getPeerKey(dialog.peer)];
|
||||||
const chat = buildApiChatFromSavedDialog(dialog, peerEntity);
|
const chat = buildApiChatFromSavedDialog(dialog, peerEntity);
|
||||||
const chatId = getApiChatIdFromMtpPeer(dialog.peer);
|
const chatId = getApiChatIdFromMtpPeer(dialog.peer);
|
||||||
@ -596,7 +600,7 @@ async function getFullChatInfo(chatId: string): Promise<FullChatData | undefined
|
|||||||
async function getFullChannelInfo(
|
async function getFullChannelInfo(
|
||||||
chat: ApiChat,
|
chat: ApiChat,
|
||||||
): Promise<FullChatData | undefined> {
|
): Promise<FullChatData | undefined> {
|
||||||
const { id, adminRights } = chat;
|
const { id, adminRights, isMonoforum } = chat;
|
||||||
const accessHash = chat.accessHash!;
|
const accessHash = chat.accessHash!;
|
||||||
const result = await invokeRequest(new GramJs.channels.GetFullChannel({
|
const result = await invokeRequest(new GramJs.channels.GetFullChannel({
|
||||||
channel: buildInputChannel(id, accessHash),
|
channel: buildInputChannel(id, accessHash),
|
||||||
@ -653,12 +657,14 @@ async function getFullChannelInfo(
|
|||||||
? exportedInvite.link
|
? exportedInvite.link
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const { members, userStatusesById } = (canViewParticipants && await fetchMembers({ chat })) || {};
|
const canLoadParticipants = canViewParticipants && !isMonoforum;
|
||||||
|
|
||||||
|
const { members, userStatusesById } = (canLoadParticipants && await fetchMembers({ chat })) || {};
|
||||||
const { members: kickedMembers, userStatusesById: bannedStatusesById } = (
|
const { members: kickedMembers, userStatusesById: bannedStatusesById } = (
|
||||||
canViewParticipants && adminRights && await fetchMembers({ chat, memberFilter: 'kicked' })
|
canLoadParticipants && adminRights && await fetchMembers({ chat, memberFilter: 'kicked' })
|
||||||
) || {};
|
) || {};
|
||||||
const { members: adminMembers, userStatusesById: adminStatusesById } = (
|
const { members: adminMembers, userStatusesById: adminStatusesById } = (
|
||||||
canViewParticipants && await fetchMembers({ chat, memberFilter: 'admin' })
|
canLoadParticipants && await fetchMembers({ chat, memberFilter: 'admin' })
|
||||||
) || {};
|
) || {};
|
||||||
const botCommands = botInfo ? buildApiChatBotCommands(botInfo) : undefined;
|
const botCommands = botInfo ? buildApiChatBotCommands(botInfo) : undefined;
|
||||||
const memberInfoRequest = !chat.isNotJoined && chat.type === 'chatTypeChannel'
|
const memberInfoRequest = !chat.isNotJoined && chat.type === 'chatTypeChannel'
|
||||||
@ -710,7 +716,7 @@ async function getFullChannelInfo(
|
|||||||
chatId: buildApiPeerId(migratedFromChatId, 'chat'),
|
chatId: buildApiPeerId(migratedFromChatId, 'chat'),
|
||||||
maxMessageId: migratedFromMaxId,
|
maxMessageId: migratedFromMaxId,
|
||||||
} : undefined,
|
} : undefined,
|
||||||
canViewMembers: canViewParticipants,
|
canViewMembers: canLoadParticipants,
|
||||||
canViewStatistics: canViewStats,
|
canViewStatistics: canViewStats,
|
||||||
canViewMonetization,
|
canViewMonetization,
|
||||||
isPreHistoryHidden: hiddenPrehistory,
|
isPreHistoryHidden: hiddenPrehistory,
|
||||||
|
|||||||
@ -980,8 +980,8 @@ export async function sendMessageAction({
|
|||||||
}: {
|
}: {
|
||||||
peer: ApiPeer; threadId?: ThreadId; action: ApiSendMessageAction;
|
peer: ApiPeer; threadId?: ThreadId; action: ApiSendMessageAction;
|
||||||
}) {
|
}) {
|
||||||
const gramAction = buildSendMessageAction(action);
|
const mtpAction = buildSendMessageAction(action);
|
||||||
if (!gramAction) {
|
if (!mtpAction) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.warn('Unsupported message action', action);
|
console.warn('Unsupported message action', action);
|
||||||
@ -993,7 +993,7 @@ export async function sendMessageAction({
|
|||||||
const result = await invokeRequest(new GramJs.messages.SetTyping({
|
const result = await invokeRequest(new GramJs.messages.SetTyping({
|
||||||
peer: buildInputPeer(peer.id, peer.accessHash),
|
peer: buildInputPeer(peer.id, peer.accessHash),
|
||||||
topMsgId: Number(threadId),
|
topMsgId: Number(threadId),
|
||||||
action: gramAction,
|
action: mtpAction,
|
||||||
}), {
|
}), {
|
||||||
shouldThrow: true,
|
shouldThrow: true,
|
||||||
abortControllerChatId: peer.id,
|
abortControllerChatId: peer.id,
|
||||||
|
|||||||
@ -47,6 +47,9 @@ export interface ApiChat {
|
|||||||
emojiStatus?: ApiEmojiStatusType;
|
emojiStatus?: ApiEmojiStatusType;
|
||||||
isForum?: boolean;
|
isForum?: boolean;
|
||||||
isForumAsMessages?: true;
|
isForumAsMessages?: true;
|
||||||
|
isMonoforum?: boolean;
|
||||||
|
linkedMonoforumId?: string;
|
||||||
|
areChannelMessagesAllowed?: boolean;
|
||||||
boostLevel?: number;
|
boostLevel?: number;
|
||||||
botVerificationIconId?: string;
|
botVerificationIconId?: string;
|
||||||
hasAutoTranslation?: true;
|
hasAutoTranslation?: true;
|
||||||
|
|||||||
@ -278,6 +278,7 @@ export interface ApiMessageActionPaidMessagesRefunded extends ActionMediaType {
|
|||||||
export interface ApiMessageActionPaidMessagesPrice extends ActionMediaType {
|
export interface ApiMessageActionPaidMessagesPrice extends ActionMediaType {
|
||||||
type: 'paidMessagesPrice';
|
type: 'paidMessagesPrice';
|
||||||
stars: number;
|
stars: number;
|
||||||
|
isAllowedInChannel?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApiMessageActionUnsupported extends ActionMediaType {
|
export interface ApiMessageActionUnsupported extends ActionMediaType {
|
||||||
|
|||||||
@ -379,6 +379,7 @@ export interface ApiInputMessageReplyInfo {
|
|||||||
replyToMsgId: number;
|
replyToMsgId: number;
|
||||||
replyToTopId?: number;
|
replyToTopId?: number;
|
||||||
replyToPeerId?: string;
|
replyToPeerId?: string;
|
||||||
|
monoforumPeerId?: string;
|
||||||
quoteText?: ApiFormattedText;
|
quoteText?: ApiFormattedText;
|
||||||
quoteOffset?: number;
|
quoteOffset?: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -250,6 +250,7 @@ export interface ApiAppConfig {
|
|||||||
starsStargiftResaleAmountMin?: number;
|
starsStargiftResaleAmountMin?: number;
|
||||||
starsStargiftResaleAmountMax?: number;
|
starsStargiftResaleAmountMax?: number;
|
||||||
starsStargiftResaleCommissionPermille?: number;
|
starsStargiftResaleCommissionPermille?: number;
|
||||||
|
pollMaxAnswers?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApiConfig {
|
export interface ApiConfig {
|
||||||
|
|||||||
@ -1918,7 +1918,8 @@
|
|||||||
"SectionDescriptionStarsForForMessages" = "You will receive {percent} of the selected fee (~{amount}) for each incoming message.";
|
"SectionDescriptionStarsForForMessages" = "You will receive {percent} of the selected fee (~{amount}) for each incoming message.";
|
||||||
"SubtitlePrivacyAddUsers" = "Add Users";
|
"SubtitlePrivacyAddUsers" = "Add Users";
|
||||||
"PrivacyPaidMessagesValue" = "Paid";
|
"PrivacyPaidMessagesValue" = "Paid";
|
||||||
"FirstMessageInPaidMessagesChat" = "**{user}** charges {amount} for each message.";
|
"MessagesPlaceholderPaidUser" = "**{peer}** charges {amount} for each message.";
|
||||||
|
"MessagesPlaceholderPaidChannel" = "**{peer}** charges {amount} per message to its admin.";
|
||||||
"ButtonBuyStars" = "Buy Stars";
|
"ButtonBuyStars" = "Buy Stars";
|
||||||
"ComposerPlaceholderPaidMessage" = "Message for {amount}";
|
"ComposerPlaceholderPaidMessage" = "Message for {amount}";
|
||||||
"ComposerPlaceholderPaidReply" = "Reply for {amount}";
|
"ComposerPlaceholderPaidReply" = "Reply for {amount}";
|
||||||
@ -1965,8 +1966,12 @@
|
|||||||
"FrozenAccountAppealSubtitle" = "Appeal via {botLink} before {date} or your account will be deleted.";
|
"FrozenAccountAppealSubtitle" = "Appeal via {botLink} before {date} or your account will be deleted.";
|
||||||
"ButtonAppeal" = "Submit an Appeal";
|
"ButtonAppeal" = "Submit an Appeal";
|
||||||
"ButtonUnderstood" = "Understood";
|
"ButtonUnderstood" = "Understood";
|
||||||
"ActionPaidMessageGroupPrice" = "Messages now cost **{stars}** in this group";
|
"ActionPaidMessagePrice" = "{peer} changed price to **{amount}** per message";
|
||||||
"ActionPaidMessageGroupPriceFree" = "Messages are now free in this group";
|
"ActionPaidMessagePriceYou" = "You changed price to **{amount}** per message";
|
||||||
|
"ActionPaidMessagePriceFree" = "{peer} made messages free";
|
||||||
|
"ActionPaidMessagePriceFreeYou" = "You made messages free";
|
||||||
|
"ActionMessageChannelFree" = "{peer} now accepts private messages";
|
||||||
|
"ActionMessageChannelDisabled" = "{peer} no longer accepts private messages";
|
||||||
"ApiMessageActionPaidMessagesRefundedOutgoing" = "You refunded **{stars}** to {user}";
|
"ApiMessageActionPaidMessagesRefundedOutgoing" = "You refunded **{stars}** to {user}";
|
||||||
"ApiMessageActionPaidMessagesRefundedIncoming" = "{user} refunded **{stars}** to you";
|
"ApiMessageActionPaidMessagesRefundedIncoming" = "{user} refunded **{stars}** to you";
|
||||||
"NotificationTitleNotSupportedInFrozenAccount" = "Your account is frozen";
|
"NotificationTitleNotSupportedInFrozenAccount" = "Your account is frozen";
|
||||||
@ -2012,4 +2017,8 @@
|
|||||||
"ValueGiftSortByNumber" = "Number";
|
"ValueGiftSortByNumber" = "Number";
|
||||||
"ResellGiftsNoFound" = "No gifts found";
|
"ResellGiftsNoFound" = "No gifts found";
|
||||||
"ResellGiftsClearFilters" = "Clear Filters";
|
"ResellGiftsClearFilters" = "Clear Filters";
|
||||||
|
"MonoforumBadge" = "DIRECT";
|
||||||
|
"MonoforumStatus" = "Channel messages";
|
||||||
|
"MonoforumComposerPlaceholder" = "Choose a message to reply";
|
||||||
|
"ChannelSendMessage" = "Direct Messages";
|
||||||
"AutomaticTranslation" = "Automatic Translation";
|
"AutomaticTranslation" = "Automatic Translation";
|
||||||
|
|||||||
@ -150,4 +150,13 @@
|
|||||||
&.premium-gradient-bg > .inner {
|
&.premium-gradient-bg > .inner {
|
||||||
background-image: var(--premium-gradient);
|
background-image: var(--premium-gradient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.message-bubble {
|
||||||
|
--radius: 0;
|
||||||
|
|
||||||
|
mask-image: url("../../assets/icons/forumTopic/blue.svg");
|
||||||
|
mask-position: center;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-size: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,6 +85,7 @@ type OwnProps = {
|
|||||||
storyViewerMode?: 'full' | 'single-peer' | 'disabled';
|
storyViewerMode?: 'full' | 'single-peer' | 'disabled';
|
||||||
loopIndefinitely?: boolean;
|
loopIndefinitely?: boolean;
|
||||||
noPersonalPhoto?: boolean;
|
noPersonalPhoto?: boolean;
|
||||||
|
asMessageBubble?: boolean;
|
||||||
observeIntersection?: ObserveFn;
|
observeIntersection?: ObserveFn;
|
||||||
onClick?: (e: ReactMouseEvent<HTMLDivElement, MouseEvent>, hasMedia: boolean) => void;
|
onClick?: (e: ReactMouseEvent<HTMLDivElement, MouseEvent>, hasMedia: boolean) => void;
|
||||||
onContextMenu?: (e: React.MouseEvent) => void;
|
onContextMenu?: (e: React.MouseEvent) => void;
|
||||||
@ -111,6 +112,7 @@ const Avatar: FC<OwnProps> = ({
|
|||||||
storyViewerMode = 'single-peer',
|
storyViewerMode = 'single-peer',
|
||||||
loopIndefinitely,
|
loopIndefinitely,
|
||||||
noPersonalPhoto,
|
noPersonalPhoto,
|
||||||
|
asMessageBubble,
|
||||||
onClick,
|
onClick,
|
||||||
onContextMenu,
|
onContextMenu,
|
||||||
}) => {
|
}) => {
|
||||||
@ -261,6 +263,7 @@ const Avatar: FC<OwnProps> = ({
|
|||||||
isReplies && 'replies-bot-account',
|
isReplies && 'replies-bot-account',
|
||||||
isPremiumGradient && 'premium-gradient-bg',
|
isPremiumGradient && 'premium-gradient-bg',
|
||||||
isRoundedRect && 'forum',
|
isRoundedRect && 'forum',
|
||||||
|
asMessageBubble && 'message-bubble',
|
||||||
(photo || webPhoto) && 'force-fit',
|
(photo || webPhoto) && 'force-fit',
|
||||||
((withStory && realPeer?.hasStories) || forPremiumPromo) && 'with-story-circle',
|
((withStory && realPeer?.hasStories) || forPremiumPromo) && 'with-story-circle',
|
||||||
withStorySolid && realPeer?.hasStories && 'with-story-solid',
|
withStorySolid && realPeer?.hasStories && 'with-story-solid',
|
||||||
|
|||||||
@ -300,6 +300,7 @@ type StateProps =
|
|||||||
isAccountFrozen?: boolean;
|
isAccountFrozen?: boolean;
|
||||||
isAppConfigLoaded?: boolean;
|
isAppConfigLoaded?: boolean;
|
||||||
insertingPeerIdMention?: string;
|
insertingPeerIdMention?: string;
|
||||||
|
pollMaxAnswers?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MainButtonState {
|
enum MainButtonState {
|
||||||
@ -413,10 +414,6 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
shouldPlayEffect,
|
shouldPlayEffect,
|
||||||
maxMessageLength,
|
maxMessageLength,
|
||||||
isSilentPosting,
|
isSilentPosting,
|
||||||
onDropHide,
|
|
||||||
onFocus,
|
|
||||||
onBlur,
|
|
||||||
onForward,
|
|
||||||
isPaymentMessageConfirmDialogOpen,
|
isPaymentMessageConfirmDialogOpen,
|
||||||
starsBalance,
|
starsBalance,
|
||||||
isStarsBalanceModalOpen,
|
isStarsBalanceModalOpen,
|
||||||
@ -424,6 +421,11 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
isAccountFrozen,
|
isAccountFrozen,
|
||||||
isAppConfigLoaded,
|
isAppConfigLoaded,
|
||||||
insertingPeerIdMention,
|
insertingPeerIdMention,
|
||||||
|
pollMaxAnswers,
|
||||||
|
onDropHide,
|
||||||
|
onFocus,
|
||||||
|
onBlur,
|
||||||
|
onForward,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
sendMessage,
|
sendMessage,
|
||||||
@ -481,9 +483,12 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
const canMediaBeReplaced = editingMessage && canEditMedia(editingMessage);
|
const canMediaBeReplaced = editingMessage && canEditMedia(editingMessage);
|
||||||
|
|
||||||
|
const isMonoforum = chat?.isMonoforum;
|
||||||
const { emojiSet, members: groupChatMembers, botCommands: chatBotCommands } = chatFullInfo || {};
|
const { emojiSet, members: groupChatMembers, botCommands: chatBotCommands } = chatFullInfo || {};
|
||||||
const chatEmojiSetId = emojiSet?.id;
|
const chatEmojiSetId = emojiSet?.id;
|
||||||
|
|
||||||
|
const canSchedule = !paidMessagesStars && !isMonoforum;
|
||||||
|
|
||||||
const isSentStoryReactionHeart = sentStoryReaction && isSameReaction(sentStoryReaction, HEART_REACTION);
|
const isSentStoryReactionHeart = sentStoryReaction && isSameReaction(sentStoryReaction, HEART_REACTION);
|
||||||
|
|
||||||
useEffect(processMessageInputForCustomEmoji, [getHtml]);
|
useEffect(processMessageInputForCustomEmoji, [getHtml]);
|
||||||
@ -510,10 +515,10 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
}, [chatId]);
|
}, [chatId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isAppConfigLoaded && chatId && isReady && !isInStoryViewer) {
|
if (isAppConfigLoaded && chatId && isReady && !isInStoryViewer && !isMonoforum) {
|
||||||
loadScheduledHistory({ chatId });
|
loadScheduledHistory({ chatId });
|
||||||
}
|
}
|
||||||
}, [isReady, chatId, threadId, isInStoryViewer, isAppConfigLoaded]);
|
}, [isReady, chatId, threadId, isInStoryViewer, isAppConfigLoaded, isMonoforum]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const isChannelWithProfiles = isChannel && chat?.areProfilesShown;
|
const isChannelWithProfiles = isChannel && chat?.areProfilesShown;
|
||||||
@ -541,10 +546,11 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
() => getAllowedAttachmentOptions(chat,
|
() => getAllowedAttachmentOptions(chat,
|
||||||
chatFullInfo,
|
chatFullInfo,
|
||||||
isChatWithBot,
|
isChatWithBot,
|
||||||
|
isChatWithSelf,
|
||||||
isInStoryViewer,
|
isInStoryViewer,
|
||||||
paidMessagesStars,
|
paidMessagesStars,
|
||||||
isInScheduledList),
|
isInScheduledList),
|
||||||
[chat, chatFullInfo, isChatWithBot, isInStoryViewer, paidMessagesStars, isInScheduledList],
|
[chat, chatFullInfo, isChatWithBot, isChatWithSelf, isInStoryViewer, paidMessagesStars, isInScheduledList],
|
||||||
);
|
);
|
||||||
|
|
||||||
const isNeedPremium = isContactRequirePremium && isInStoryViewer;
|
const isNeedPremium = isContactRequirePremium && isInStoryViewer;
|
||||||
@ -804,7 +810,7 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
getHtml,
|
getHtml,
|
||||||
setHtml,
|
setHtml,
|
||||||
editedMessage: editingMessage,
|
editedMessage: editingMessage,
|
||||||
isDisabled: isInStoryViewer || Boolean(requestedDraft),
|
isDisabled: isInStoryViewer || Boolean(requestedDraft) || isMonoforum,
|
||||||
});
|
});
|
||||||
|
|
||||||
const resetComposer = useLastCallback((shouldPreserveInput = false) => {
|
const resetComposer = useLastCallback((shouldPreserveInput = false) => {
|
||||||
@ -1847,8 +1853,8 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
shouldForceAsFile={shouldForceAsFile}
|
shouldForceAsFile={shouldForceAsFile}
|
||||||
isForCurrentMessageList={isForCurrentMessageList}
|
isForCurrentMessageList={isForCurrentMessageList}
|
||||||
isForMessage={isInMessageList}
|
isForMessage={isInMessageList}
|
||||||
shouldSchedule={!paidMessagesStars && isInScheduledList}
|
shouldSchedule={canSchedule && isInScheduledList}
|
||||||
canSchedule={!paidMessagesStars}
|
canSchedule={canSchedule}
|
||||||
forceDarkTheme={isInStoryViewer}
|
forceDarkTheme={isInStoryViewer}
|
||||||
onCaptionUpdate={onCaptionUpdate}
|
onCaptionUpdate={onCaptionUpdate}
|
||||||
onSendSilent={handleSendSilentAttachments}
|
onSendSilent={handleSendSilentAttachments}
|
||||||
@ -1869,6 +1875,7 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
isOpen={pollModal.isOpen}
|
isOpen={pollModal.isOpen}
|
||||||
isQuiz={pollModal.isQuiz}
|
isQuiz={pollModal.isQuiz}
|
||||||
shouldBeAnonymous={isChannel}
|
shouldBeAnonymous={isChannel}
|
||||||
|
maxOptionsCount={pollMaxAnswers}
|
||||||
onClear={closePollModal}
|
onClear={closePollModal}
|
||||||
onSend={handlePollSend}
|
onSend={handlePollSend}
|
||||||
/>
|
/>
|
||||||
@ -2304,7 +2311,7 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
{canShowCustomSendMenu && (
|
{canShowCustomSendMenu && (
|
||||||
<CustomSendMenu
|
<CustomSendMenu
|
||||||
isOpen={isCustomSendMenuOpen}
|
isOpen={isCustomSendMenuOpen}
|
||||||
canSchedule={!paidMessagesStars && isInMessageList && !isViewOnceEnabled}
|
canSchedule={canSchedule && isInMessageList && !isViewOnceEnabled}
|
||||||
canScheduleUntilOnline={canScheduleUntilOnline && !isViewOnceEnabled}
|
canScheduleUntilOnline={canScheduleUntilOnline && !isViewOnceEnabled}
|
||||||
onSendSilent={!isChatWithSelf ? handleSendSilent : undefined}
|
onSendSilent={!isChatWithSelf ? handleSendSilent : undefined}
|
||||||
onSendSchedule={!isInScheduledList ? handleSendScheduled : undefined}
|
onSendSchedule={!isInScheduledList ? handleSendScheduled : undefined}
|
||||||
@ -2344,6 +2351,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
(global, {
|
(global, {
|
||||||
chatId, threadId, storyId, messageListType, isMobile, type,
|
chatId, threadId, storyId, messageListType, isMobile, type,
|
||||||
}): StateProps => {
|
}): StateProps => {
|
||||||
|
const appConfig = global.appConfig;
|
||||||
const chat = selectChat(global, chatId);
|
const chat = selectChat(global, chatId);
|
||||||
const chatBot = !isSystemBot(chatId) ? selectBot(global, chatId) : undefined;
|
const chatBot = !isSystemBot(chatId) ? selectBot(global, chatId) : undefined;
|
||||||
const isChatWithBot = Boolean(chatBot);
|
const isChatWithBot = Boolean(chatBot);
|
||||||
@ -2514,6 +2522,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
isAccountFrozen,
|
isAccountFrozen,
|
||||||
isAppConfigLoaded,
|
isAppConfigLoaded,
|
||||||
insertingPeerIdMention,
|
insertingPeerIdMention,
|
||||||
|
pollMaxAnswers: appConfig?.pollMaxAnswers,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(Composer));
|
)(Composer));
|
||||||
|
|||||||
@ -90,11 +90,11 @@ const DeleteMessageModal: FC<OwnProps & StateProps> = ({
|
|||||||
contactName,
|
contactName,
|
||||||
willDeleteForCurrentUserOnly,
|
willDeleteForCurrentUserOnly,
|
||||||
willDeleteForAll,
|
willDeleteForAll,
|
||||||
onConfirm,
|
|
||||||
chatBot,
|
chatBot,
|
||||||
adminMembersById,
|
adminMembersById,
|
||||||
canBanUsers,
|
canBanUsers,
|
||||||
linkedChatId,
|
linkedChatId,
|
||||||
|
onConfirm,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
closeDeleteMessageModal,
|
closeDeleteMessageModal,
|
||||||
@ -130,7 +130,11 @@ const DeleteMessageModal: FC<OwnProps & StateProps> = ({
|
|||||||
const global = getGlobal();
|
const global = getGlobal();
|
||||||
const senderArray = getSendersFromSelectedMessages(global, chat.id, messageIds);
|
const senderArray = getSendersFromSelectedMessages(global, chat.id, messageIds);
|
||||||
return senderArray ? unique(senderArray)
|
return senderArray ? unique(senderArray)
|
||||||
.filter((peer) => peer?.id !== chat?.id && peer?.id !== linkedChatId) : MEMO_EMPTY_ARRAY;
|
.filter((peer) => (
|
||||||
|
peer?.id !== chat?.id
|
||||||
|
&& peer?.id !== linkedChatId
|
||||||
|
&& peer?.id !== chat?.linkedMonoforumId
|
||||||
|
)) : MEMO_EMPTY_ARRAY;
|
||||||
}, [chat, isChannel, linkedChatId, messageIds]);
|
}, [chat, isChannel, linkedChatId, messageIds]);
|
||||||
|
|
||||||
const buildNestedOptionListWithAvatars = useLastCallback(() => {
|
const buildNestedOptionListWithAvatars = useLastCallback(() => {
|
||||||
@ -144,16 +148,24 @@ const DeleteMessageModal: FC<OwnProps & StateProps> = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const peerListToDeleteAll = useMemo(() => {
|
const peerListToDeleteAll = useMemo(() => {
|
||||||
return peerList.filter((peer) => peer.id !== linkedChatId && peer.id !== currentUserId);
|
return peerList.filter((peer) => (
|
||||||
}, [peerList, currentUserId, linkedChatId]);
|
peer.id !== linkedChatId
|
||||||
|
&& peer.id !== chat?.linkedMonoforumId
|
||||||
|
&& peer.id !== currentUserId
|
||||||
|
));
|
||||||
|
}, [peerList, currentUserId, linkedChatId, chat?.linkedMonoforumId]);
|
||||||
|
|
||||||
const peerListToReportSpam = useMemo(() => {
|
const peerListToReportSpam = useMemo(() => {
|
||||||
return peerList.filter((peer) => peer.id !== currentUserId && peer.id !== linkedChatId);
|
return peerList.filter((peer) => (
|
||||||
}, [peerList, currentUserId, linkedChatId]);
|
peer.id !== currentUserId
|
||||||
|
&& peer.id !== linkedChatId
|
||||||
|
&& peer.id !== chat?.linkedMonoforumId
|
||||||
|
));
|
||||||
|
}, [peerList, currentUserId, linkedChatId, chat?.linkedMonoforumId]);
|
||||||
|
|
||||||
const peerListToBan = useMemo(() => {
|
const peerListToBan = useMemo(() => {
|
||||||
const isCurrentUserInList = peerList.some((peer) => peer.id === currentUserId);
|
const isCurrentUserInList = peerList.some((peer) => peer.id === currentUserId);
|
||||||
const shouldReturnEmpty = !canBanUsers || isCurrentUserInList;
|
const shouldReturnEmpty = !canBanUsers || isCurrentUserInList || chat?.isMonoforum;
|
||||||
|
|
||||||
if (shouldReturnEmpty) {
|
if (shouldReturnEmpty) {
|
||||||
return MEMO_EMPTY_ARRAY;
|
return MEMO_EMPTY_ARRAY;
|
||||||
@ -163,7 +175,7 @@ const DeleteMessageModal: FC<OwnProps & StateProps> = ({
|
|||||||
const isAdmin = adminMembersById?.[peer.id];
|
const isAdmin = adminMembersById?.[peer.id];
|
||||||
return isCreator || !isAdmin;
|
return isCreator || !isAdmin;
|
||||||
});
|
});
|
||||||
}, [peerList, isCreator, currentUserId, canBanUsers, adminMembersById]);
|
}, [peerList, isCreator, currentUserId, canBanUsers, adminMembersById, chat?.isMonoforum]);
|
||||||
|
|
||||||
const shouldShowAdditionalOptions = useMemo(() => {
|
const shouldShowAdditionalOptions = useMemo(() => {
|
||||||
return Boolean(peerListToDeleteAll.length || peerListToReportSpam.length || peerListToBan.length);
|
return Boolean(peerListToDeleteAll.length || peerListToReportSpam.length || peerListToBan.length);
|
||||||
@ -184,11 +196,12 @@ const DeleteMessageModal: FC<OwnProps & StateProps> = ({
|
|||||||
label: oldLang('ReportSpamTitle'),
|
label: oldLang('ReportSpamTitle'),
|
||||||
nestedOptions: messageIds && peerList.length >= 2 ? [
|
nestedOptions: messageIds && peerList.length >= 2 ? [
|
||||||
...buildNestedOptionListWithAvatars().filter((opt) => opt.value !== linkedChatId
|
...buildNestedOptionListWithAvatars().filter((opt) => opt.value !== linkedChatId
|
||||||
|
&& opt.value !== chat?.linkedMonoforumId
|
||||||
&& opt.value !== currentUserId),
|
&& opt.value !== currentUserId),
|
||||||
] : undefined,
|
] : undefined,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}, [messageIds, peerList, oldLang, linkedChatId, currentUserId]);
|
}, [messageIds, peerList, oldLang, linkedChatId, chat?.linkedMonoforumId, currentUserId]);
|
||||||
|
|
||||||
const ACTION_DELETE_OPTION: IRadioOption[] = useMemo(() => {
|
const ACTION_DELETE_OPTION: IRadioOption[] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
@ -199,11 +212,12 @@ const DeleteMessageModal: FC<OwnProps & StateProps> = ({
|
|||||||
: oldLang('DeleteAllFrom', Object.values(peerNames)[0]),
|
: oldLang('DeleteAllFrom', Object.values(peerNames)[0]),
|
||||||
nestedOptions: messageIds && peerList.length >= 2 ? [
|
nestedOptions: messageIds && peerList.length >= 2 ? [
|
||||||
...buildNestedOptionListWithAvatars().filter((opt) => opt.value !== linkedChatId
|
...buildNestedOptionListWithAvatars().filter((opt) => opt.value !== linkedChatId
|
||||||
|
&& opt.value !== chat?.linkedMonoforumId
|
||||||
&& opt.value !== currentUserId),
|
&& opt.value !== currentUserId),
|
||||||
] : undefined,
|
] : undefined,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}, [messageIds, peerList, oldLang, peerNames, linkedChatId, currentUserId]);
|
}, [messageIds, peerList, oldLang, peerNames, linkedChatId, chat?.linkedMonoforumId, currentUserId]);
|
||||||
|
|
||||||
const ACTION_BAN_OPTION: IRadioOption[] = useMemo(() => {
|
const ACTION_BAN_OPTION: IRadioOption[] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
@ -279,7 +293,7 @@ const DeleteMessageModal: FC<OwnProps & StateProps> = ({
|
|||||||
if (isSchedule) {
|
if (isSchedule) {
|
||||||
deleteScheduledMessages({ messageIds });
|
deleteScheduledMessages({ messageIds });
|
||||||
} else if (shouldShowOption) {
|
} else if (shouldShowOption) {
|
||||||
if (peerIdsToReportSpam) {
|
if (peerIdsToReportSpam?.length) {
|
||||||
const global = getGlobal();
|
const global = getGlobal();
|
||||||
const peerIdList = peerIdsToReportSpam.filter((option) => !Number.isNaN(Number(option)));
|
const peerIdList = peerIdsToReportSpam.filter((option) => !Number.isNaN(Number(option)));
|
||||||
const messageList = messageIds.reduce<Record<string, number[]>>((acc, msgId) => {
|
const messageList = messageIds.reduce<Record<string, number[]>>((acc, msgId) => {
|
||||||
@ -296,24 +310,24 @@ const DeleteMessageModal: FC<OwnProps & StateProps> = ({
|
|||||||
handleReportSpam(messageList);
|
handleReportSpam(messageList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peerIdsToDeleteAll) {
|
if (peerIdsToDeleteAll?.length) {
|
||||||
const peerIdList = peerIdsToDeleteAll.filter((option) => !Number.isNaN(Number(option)));
|
const peerIdList = peerIdsToDeleteAll.filter((option) => !Number.isNaN(Number(option)));
|
||||||
handleDeleteAllPeerMessages(peerIdList);
|
handleDeleteAllPeerMessages(peerIdList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peerIdsToBan && !havePermissionChanged) {
|
if (peerIdsToBan?.length && !havePermissionChanged) {
|
||||||
const peerIdList = peerIdsToBan.filter((option) => !Number.isNaN(Number(option)));
|
const peerIdList = peerIdsToBan.filter((option) => !Number.isNaN(Number(option)));
|
||||||
handleDeleteMember(peerIdList);
|
handleDeleteMember(peerIdList);
|
||||||
const filteredMessageIdList = filterMessageIdByPeerId(peerIdList, messageIds);
|
const filteredMessageIdList = filterMessageIdByPeerId(peerIdList, messageIds);
|
||||||
handleDeleteMessages(filteredMessageIdList);
|
handleDeleteMessages(filteredMessageIdList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peerIdsToBan && havePermissionChanged) {
|
if (peerIdsToBan?.length && havePermissionChanged) {
|
||||||
const peerIdList = peerIdsToBan.filter((option) => !Number.isNaN(Number(option)));
|
const peerIdList = peerIdsToBan.filter((option) => !Number.isNaN(Number(option)));
|
||||||
handleUpdateChatMemberBannedRights(peerIdList);
|
handleUpdateChatMemberBannedRights(peerIdList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!peerIdsToReportSpam || !peerIdsToDeleteAll || !peerIdsToBan) {
|
if (!peerIdsToReportSpam?.length || !peerIdsToDeleteAll?.length || !peerIdsToBan?.length) {
|
||||||
deleteMessages({ messageIds, shouldDeleteForAll });
|
deleteMessages({ messageIds, shouldDeleteForAll });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -426,21 +440,19 @@ const DeleteMessageModal: FC<OwnProps & StateProps> = ({
|
|||||||
<p className={styles.actionTitle}>{oldLang('DeleteAdditionalActions')}</p>
|
<p className={styles.actionTitle}>{oldLang('DeleteAdditionalActions')}</p>
|
||||||
{renderAdditionalActionOptions()}
|
{renderAdditionalActionOptions()}
|
||||||
{renderPartiallyRestrictedUser()}
|
{renderPartiallyRestrictedUser()}
|
||||||
{
|
{peerIdsToBan?.length && canBanUsers ? (
|
||||||
peerIdsToBan && canBanUsers ? (
|
<ListItem
|
||||||
<ListItem
|
narrow
|
||||||
narrow
|
buttonClassName={styles.button}
|
||||||
buttonClassName={styles.button}
|
onClick={toggleAdditionalOptions}
|
||||||
onClick={toggleAdditionalOptions}
|
>
|
||||||
>
|
{oldLang(isAdditionalOptionsVisible ? 'DeleteToggleBanUsers' : 'DeleteToggleRestrictUsers')}
|
||||||
{oldLang(isAdditionalOptionsVisible ? 'DeleteToggleBanUsers' : 'DeleteToggleRestrictUsers')}
|
<Icon
|
||||||
<Icon
|
name={isAdditionalOptionsVisible ? 'up' : 'down'}
|
||||||
name={isAdditionalOptionsVisible ? 'up' : 'down'}
|
className={buildClassName(styles.button, 'ml-2')}
|
||||||
className={buildClassName(styles.button, 'ml-2')}
|
/>
|
||||||
/>
|
</ListItem>
|
||||||
</ListItem>
|
) : setIsAdditionalOptionsVisible(false)}
|
||||||
) : setIsAdditionalOptionsVisible(false)
|
|
||||||
}
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{(canDeleteForAll || chatBot || !shouldShowOption) && (
|
{(canDeleteForAll || chatBot || !shouldShowOption) && (
|
||||||
|
|||||||
@ -38,3 +38,15 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.monoforumBadge {
|
||||||
|
padding: 0.125rem 0.25rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
|
||||||
|
font-size: 0.625rem;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1;
|
||||||
|
color: var(--color-white);
|
||||||
|
|
||||||
|
background-color: var(--color-gray);
|
||||||
|
}
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import { copyTextToClipboard } from '../../util/clipboard';
|
|||||||
import stopEvent from '../../util/stopEvent';
|
import stopEvent from '../../util/stopEvent';
|
||||||
import renderText from './helpers/renderText';
|
import renderText from './helpers/renderText';
|
||||||
|
|
||||||
|
import useLang from '../../hooks/useLang';
|
||||||
import useLastCallback from '../../hooks/useLastCallback';
|
import useLastCallback from '../../hooks/useLastCallback';
|
||||||
import useOldLang from '../../hooks/useOldLang';
|
import useOldLang from '../../hooks/useOldLang';
|
||||||
|
|
||||||
@ -44,12 +45,14 @@ type OwnProps = {
|
|||||||
emojiStatusSize?: number;
|
emojiStatusSize?: number;
|
||||||
isSavedMessages?: boolean;
|
isSavedMessages?: boolean;
|
||||||
isSavedDialog?: boolean;
|
isSavedDialog?: boolean;
|
||||||
|
isMonoforum?: boolean;
|
||||||
|
monoforumBadgeClassName?: string;
|
||||||
noLoopLimit?: boolean;
|
noLoopLimit?: boolean;
|
||||||
canCopyTitle?: boolean;
|
canCopyTitle?: boolean;
|
||||||
iconElement?: React.ReactNode;
|
iconElement?: React.ReactNode;
|
||||||
|
statusSparklesColor?: string;
|
||||||
onEmojiStatusClick?: NoneToVoidFunction;
|
onEmojiStatusClick?: NoneToVoidFunction;
|
||||||
observeIntersection?: ObserveFn;
|
observeIntersection?: ObserveFn;
|
||||||
statusSparklesColor?: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const FullNameTitle: FC<OwnProps> = ({
|
const FullNameTitle: FC<OwnProps> = ({
|
||||||
@ -65,15 +68,20 @@ const FullNameTitle: FC<OwnProps> = ({
|
|||||||
canCopyTitle,
|
canCopyTitle,
|
||||||
iconElement,
|
iconElement,
|
||||||
statusSparklesColor,
|
statusSparklesColor,
|
||||||
|
isMonoforum,
|
||||||
|
monoforumBadgeClassName,
|
||||||
onEmojiStatusClick,
|
onEmojiStatusClick,
|
||||||
observeIntersection,
|
observeIntersection,
|
||||||
}) => {
|
}) => {
|
||||||
const lang = useOldLang();
|
|
||||||
const { showNotification } = getActions();
|
const { showNotification } = getActions();
|
||||||
|
|
||||||
|
const oldLang = useOldLang();
|
||||||
|
const lang = useLang();
|
||||||
|
|
||||||
const realPeer = 'id' in peer ? peer : undefined;
|
const realPeer = 'id' in peer ? peer : undefined;
|
||||||
const customPeer = 'isCustomPeer' in peer ? peer : undefined;
|
const customPeer = 'isCustomPeer' in peer ? peer : undefined;
|
||||||
const isUser = realPeer && isApiPeerUser(realPeer);
|
const isUser = realPeer && isApiPeerUser(realPeer);
|
||||||
const title = realPeer && (isUser ? getUserFullName(realPeer) : getChatTitle(lang, realPeer));
|
const title = realPeer && (isUser ? getUserFullName(realPeer) : getChatTitle(oldLang, realPeer));
|
||||||
const isPremium = (isUser && realPeer.isPremium) || customPeer?.isPremium;
|
const isPremium = (isUser && realPeer.isPremium) || customPeer?.isPremium;
|
||||||
const canShowEmojiStatus = withEmojiStatus && !isSavedMessages;
|
const canShowEmojiStatus = withEmojiStatus && !isSavedMessages;
|
||||||
const emojiStatus = realPeer?.emojiStatus
|
const emojiStatus = realPeer?.emojiStatus
|
||||||
@ -91,27 +99,27 @@ const FullNameTitle: FC<OwnProps> = ({
|
|||||||
|
|
||||||
const specialTitle = useMemo(() => {
|
const specialTitle = useMemo(() => {
|
||||||
if (customPeer) {
|
if (customPeer) {
|
||||||
return renderText(customPeer.title || lang(customPeer.titleKey!));
|
return renderText(customPeer.title || oldLang(customPeer.titleKey!));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSavedMessages) {
|
if (isSavedMessages) {
|
||||||
return lang(isSavedDialog ? 'MyNotes' : 'SavedMessages');
|
return oldLang(isSavedDialog ? 'MyNotes' : 'SavedMessages');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAnonymousForwardsChat(realPeer!.id)) {
|
if (isAnonymousForwardsChat(realPeer!.id)) {
|
||||||
return lang('AnonymousForward');
|
return oldLang('AnonymousForward');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isChatWithRepliesBot(realPeer!.id)) {
|
if (isChatWithRepliesBot(realPeer!.id)) {
|
||||||
return lang('RepliesTitle');
|
return oldLang('RepliesTitle');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isChatWithVerificationCodesBot(realPeer!.id)) {
|
if (isChatWithVerificationCodesBot(realPeer!.id)) {
|
||||||
return lang('VerifyCodesNotifications');
|
return oldLang('VerifyCodesNotifications');
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}, [customPeer, isSavedDialog, isSavedMessages, lang, realPeer]);
|
}, [customPeer, isSavedDialog, isSavedMessages, oldLang, realPeer]);
|
||||||
const botVerificationIconId = realPeer?.botVerificationIconId;
|
const botVerificationIconId = realPeer?.botVerificationIconId;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -164,6 +172,11 @@ const FullNameTitle: FC<OwnProps> = ({
|
|||||||
</Transition>
|
</Transition>
|
||||||
)}
|
)}
|
||||||
{canShowEmojiStatus && !emojiStatus && isPremium && <StarIcon />}
|
{canShowEmojiStatus && !emojiStatus && isPremium && <StarIcon />}
|
||||||
|
{isMonoforum && (
|
||||||
|
<div className={buildClassName(styles.monoforumBadge, monoforumBadgeClassName)}>
|
||||||
|
{lang('MonoforumBadge')}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{iconElement}
|
{iconElement}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import {
|
|||||||
selectChat,
|
selectChat,
|
||||||
selectChatMessages,
|
selectChatMessages,
|
||||||
selectChatOnlineCount,
|
selectChatOnlineCount,
|
||||||
|
selectMonoforumChannel,
|
||||||
selectThreadInfo,
|
selectThreadInfo,
|
||||||
selectThreadMessagesCount,
|
selectThreadMessagesCount,
|
||||||
selectTopic,
|
selectTopic,
|
||||||
@ -28,6 +29,7 @@ import buildClassName from '../../util/buildClassName';
|
|||||||
import { REM } from './helpers/mediaDimensions';
|
import { REM } from './helpers/mediaDimensions';
|
||||||
import renderText from './helpers/renderText';
|
import renderText from './helpers/renderText';
|
||||||
|
|
||||||
|
import useLang from '../../hooks/useLang';
|
||||||
import useLastCallback from '../../hooks/useLastCallback';
|
import useLastCallback from '../../hooks/useLastCallback';
|
||||||
import useOldLang from '../../hooks/useOldLang';
|
import useOldLang from '../../hooks/useOldLang';
|
||||||
|
|
||||||
@ -63,20 +65,21 @@ type OwnProps = {
|
|||||||
withStory?: boolean;
|
withStory?: boolean;
|
||||||
storyViewerOrigin?: StoryViewerOrigin;
|
storyViewerOrigin?: StoryViewerOrigin;
|
||||||
isSavedDialog?: boolean;
|
isSavedDialog?: boolean;
|
||||||
|
withMonoforumStatus?: boolean;
|
||||||
onClick?: VoidFunction;
|
onClick?: VoidFunction;
|
||||||
onEmojiStatusClick?: NoneToVoidFunction;
|
onEmojiStatusClick?: NoneToVoidFunction;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps =
|
type StateProps = {
|
||||||
{
|
chat?: ApiChat;
|
||||||
chat?: ApiChat;
|
threadInfo?: ApiThreadInfo;
|
||||||
threadInfo?: ApiThreadInfo;
|
topic?: ApiTopic;
|
||||||
topic?: ApiTopic;
|
onlineCount?: number;
|
||||||
onlineCount?: number;
|
areMessagesLoaded: boolean;
|
||||||
areMessagesLoaded: boolean;
|
messagesCount?: number;
|
||||||
messagesCount?: number;
|
self?: ApiUser;
|
||||||
self?: ApiUser;
|
monoforumChannel?: ApiChat;
|
||||||
};
|
};
|
||||||
|
|
||||||
const GroupChatInfo: FC<OwnProps & StateProps> = ({
|
const GroupChatInfo: FC<OwnProps & StateProps> = ({
|
||||||
typingStatus,
|
typingStatus,
|
||||||
@ -93,7 +96,7 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
|
|||||||
withChatType,
|
withChatType,
|
||||||
threadInfo,
|
threadInfo,
|
||||||
noRtl,
|
noRtl,
|
||||||
chat,
|
chat: realChat,
|
||||||
onlineCount,
|
onlineCount,
|
||||||
areMessagesLoaded,
|
areMessagesLoaded,
|
||||||
topic,
|
topic,
|
||||||
@ -105,6 +108,8 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
|
|||||||
emojiStatusSize,
|
emojiStatusSize,
|
||||||
isSavedDialog,
|
isSavedDialog,
|
||||||
self,
|
self,
|
||||||
|
withMonoforumStatus,
|
||||||
|
monoforumChannel,
|
||||||
onClick,
|
onClick,
|
||||||
onEmojiStatusClick,
|
onEmojiStatusClick,
|
||||||
}) => {
|
}) => {
|
||||||
@ -114,7 +119,10 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
|
|||||||
loadMoreProfilePhotos,
|
loadMoreProfilePhotos,
|
||||||
} = getActions();
|
} = getActions();
|
||||||
|
|
||||||
const lang = useOldLang();
|
const chat = !withMonoforumStatus && monoforumChannel ? monoforumChannel : realChat;
|
||||||
|
|
||||||
|
const oldLang = useOldLang();
|
||||||
|
const lang = useLang();
|
||||||
|
|
||||||
const isSuperGroup = chat && isChatSuperGroup(chat);
|
const isSuperGroup = chat && isChatSuperGroup(chat);
|
||||||
const isTopic = Boolean(chat?.isForum && threadInfo && topic);
|
const isTopic = Boolean(chat?.isForum && threadInfo && topic);
|
||||||
@ -148,6 +156,24 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderStatusOrTyping() {
|
function renderStatusOrTyping() {
|
||||||
|
if (withUpdatingStatus && !areMessagesLoaded && !isRestricted) {
|
||||||
|
return (
|
||||||
|
<DotAnimation className="status" content={oldLang('Updating')} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (withMonoforumStatus) {
|
||||||
|
return (
|
||||||
|
<span className="status" dir="auto">
|
||||||
|
{lang('MonoforumStatus')}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (realChat?.isMonoforum) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
return withDots ? (
|
return withDots ? (
|
||||||
<DotAnimation className="status" content={status} />
|
<DotAnimation className="status" content={status} />
|
||||||
@ -159,12 +185,6 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (withUpdatingStatus && !areMessagesLoaded && !isRestricted) {
|
|
||||||
return (
|
|
||||||
<DotAnimation className="status" content={lang('Updating')} />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!chat) {
|
if (!chat) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@ -182,7 +202,7 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
|
|||||||
activeKey={messagesCount !== undefined ? 1 : 2}
|
activeKey={messagesCount !== undefined ? 1 : 2}
|
||||||
className="message-count-transition"
|
className="message-count-transition"
|
||||||
>
|
>
|
||||||
{messagesCount !== undefined && lang('messages', messagesCount, 'i')}
|
{messagesCount !== undefined && oldLang('messages', messagesCount, 'i')}
|
||||||
</Transition>
|
</Transition>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
@ -190,12 +210,12 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
if (withChatType) {
|
if (withChatType) {
|
||||||
return (
|
return (
|
||||||
<span className="status" dir="auto">{lang(getChatTypeString(chat))}</span>
|
<span className="status" dir="auto">{oldLang(getChatTypeString(chat))}</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const groupStatus = getGroupStatus(lang, chat);
|
const groupStatus = getGroupStatus(oldLang, chat);
|
||||||
const onlineStatus = onlineCount ? `, ${lang('OnlineCount', onlineCount, 'i')}` : undefined;
|
const onlineStatus = onlineCount ? `, ${oldLang('OnlineCount', onlineCount, 'i')}` : undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className="status">
|
<span className="status">
|
||||||
@ -211,7 +231,7 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
|
|||||||
className={
|
className={
|
||||||
buildClassName('ChatInfo', className)
|
buildClassName('ChatInfo', className)
|
||||||
}
|
}
|
||||||
dir={!noRtl && lang.isRtl ? 'rtl' : undefined}
|
dir={!noRtl && oldLang.isRtl ? 'rtl' : undefined}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
{!noAvatar && !isTopic && (
|
{!noAvatar && !isTopic && (
|
||||||
@ -231,6 +251,7 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
|
|||||||
size={avatarSize}
|
size={avatarSize}
|
||||||
peer={chat}
|
peer={chat}
|
||||||
withStory={withStory}
|
withStory={withStory}
|
||||||
|
asMessageBubble={Boolean(monoforumChannel)}
|
||||||
storyViewerOrigin={storyViewerOrigin}
|
storyViewerOrigin={storyViewerOrigin}
|
||||||
storyViewerMode="single-peer"
|
storyViewerMode="single-peer"
|
||||||
isSavedDialog={isSavedDialog}
|
isSavedDialog={isSavedDialog}
|
||||||
@ -251,6 +272,7 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
|
|||||||
: (
|
: (
|
||||||
<FullNameTitle
|
<FullNameTitle
|
||||||
peer={chat}
|
peer={chat}
|
||||||
|
isMonoforum={!withMonoforumStatus && Boolean(monoforumChannel)}
|
||||||
emojiStatusSize={emojiStatusSize}
|
emojiStatusSize={emojiStatusSize}
|
||||||
withEmojiStatus={!noEmojiStatus}
|
withEmojiStatus={!noEmojiStatus}
|
||||||
isSavedDialog={isSavedDialog}
|
isSavedDialog={isSavedDialog}
|
||||||
@ -272,6 +294,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const topic = threadId ? selectTopic(global, chatId, threadId) : undefined;
|
const topic = threadId ? selectTopic(global, chatId, threadId) : undefined;
|
||||||
const messagesCount = topic && selectThreadMessagesCount(global, chatId, threadId!);
|
const messagesCount = topic && selectThreadMessagesCount(global, chatId, threadId!);
|
||||||
const self = selectUser(global, global.currentUserId!);
|
const self = selectUser(global, global.currentUserId!);
|
||||||
|
const monoforumChannel = selectMonoforumChannel(global, chatId);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
chat,
|
chat,
|
||||||
@ -281,6 +304,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
areMessagesLoaded,
|
areMessagesLoaded,
|
||||||
messagesCount,
|
messagesCount,
|
||||||
self,
|
self,
|
||||||
|
monoforumChannel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(GroupChatInfo));
|
)(GroupChatInfo));
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import { MEMO_EMPTY_ARRAY } from '../../util/memo';
|
|||||||
import renderText from './helpers/renderText';
|
import renderText from './helpers/renderText';
|
||||||
|
|
||||||
import useIntervalForceUpdate from '../../hooks/schedulers/useIntervalForceUpdate';
|
import useIntervalForceUpdate from '../../hooks/schedulers/useIntervalForceUpdate';
|
||||||
|
import useLang from '../../hooks/useLang';
|
||||||
import useLastCallback from '../../hooks/useLastCallback';
|
import useLastCallback from '../../hooks/useLastCallback';
|
||||||
import useOldLang from '../../hooks/useOldLang';
|
import useOldLang from '../../hooks/useOldLang';
|
||||||
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
|
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
|
||||||
@ -45,6 +46,7 @@ type OwnProps = {
|
|||||||
peerId: string;
|
peerId: string;
|
||||||
forceShowSelf?: boolean;
|
forceShowSelf?: boolean;
|
||||||
canPlayVideo: boolean;
|
canPlayVideo: boolean;
|
||||||
|
isForMonoforum?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps =
|
type StateProps =
|
||||||
@ -81,6 +83,7 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
|||||||
emojiStatusSlug,
|
emojiStatusSlug,
|
||||||
profilePhotos,
|
profilePhotos,
|
||||||
peerId,
|
peerId,
|
||||||
|
isForMonoforum,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
openMediaViewer,
|
openMediaViewer,
|
||||||
@ -91,7 +94,8 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
|||||||
openUniqueGiftBySlug,
|
openUniqueGiftBySlug,
|
||||||
} = getActions();
|
} = getActions();
|
||||||
|
|
||||||
const lang = useOldLang();
|
const oldLang = useOldLang();
|
||||||
|
const lang = useLang();
|
||||||
|
|
||||||
useIntervalForceUpdate(user ? STATUS_UPDATE_INTERVAL : undefined);
|
useIntervalForceUpdate(user ? STATUS_UPDATE_INTERVAL : undefined);
|
||||||
|
|
||||||
@ -100,7 +104,7 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
|||||||
const prevAvatarOwnerId = usePreviousDeprecated(avatarOwnerId);
|
const prevAvatarOwnerId = usePreviousDeprecated(avatarOwnerId);
|
||||||
const [hasSlideAnimation, setHasSlideAnimation] = useState(true);
|
const [hasSlideAnimation, setHasSlideAnimation] = useState(true);
|
||||||
// slideOptimized doesn't work well when animation is dynamically disabled
|
// slideOptimized doesn't work well when animation is dynamically disabled
|
||||||
const slideAnimation = hasSlideAnimation ? (lang.isRtl ? 'slideRtl' : 'slide') : 'none';
|
const slideAnimation = hasSlideAnimation ? (oldLang.isRtl ? 'slideRtl' : 'slide') : 'none';
|
||||||
|
|
||||||
const [currentPhotoIndex, setCurrentPhotoIndex] = useState(0);
|
const [currentPhotoIndex, setCurrentPhotoIndex] = useState(0);
|
||||||
const isFirst = photos.length <= 1 || currentPhotoIndex === 0;
|
const isFirst = photos.length <= 1 || currentPhotoIndex === 0;
|
||||||
@ -217,9 +221,9 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
|||||||
letterClassName={styles.topicIconTitle}
|
letterClassName={styles.topicIconTitle}
|
||||||
noLoopLimit
|
noLoopLimit
|
||||||
/>
|
/>
|
||||||
<h3 className={styles.topicTitle} dir={lang.isRtl ? 'rtl' : undefined}>{renderText(topic!.title)}</h3>
|
<h3 className={styles.topicTitle} dir={oldLang.isRtl ? 'rtl' : undefined}>{renderText(topic!.title)}</h3>
|
||||||
<p className={styles.topicMessagesCounter}>
|
<p className={styles.topicMessagesCounter}>
|
||||||
{messagesCount ? lang('Chat.Title.Topic', messagesCount, 'i') : lang('lng_forum_no_messages')}
|
{messagesCount ? oldLang('Chat.Title.Topic', messagesCount, 'i') : oldLang('lng_forum_no_messages')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -265,6 +269,14 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
|||||||
const isSystemBotChat = isSystemBot(peerId);
|
const isSystemBotChat = isSystemBot(peerId);
|
||||||
if (isAnonymousForwards || isSystemBotChat) return undefined;
|
if (isAnonymousForwards || isSystemBotChat) return undefined;
|
||||||
|
|
||||||
|
if (isForMonoforum) {
|
||||||
|
return (
|
||||||
|
<span className={buildClassName(styles.status, 'status')} dir="auto">
|
||||||
|
{lang('MonoforumStatus')}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -275,11 +287,11 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<span className={styles.userStatus} dir="auto">
|
<span className={styles.userStatus} dir="auto">
|
||||||
{getUserStatus(lang, user, userStatus)}
|
{getUserStatus(oldLang, user, userStatus)}
|
||||||
</span>
|
</span>
|
||||||
{userStatus?.isReadDateRestrictedByMe && (
|
{userStatus?.isReadDateRestrictedByMe && (
|
||||||
<span className={styles.getStatus} onClick={handleOpenGetReadDateModal}>
|
<span className={styles.getStatus} onClick={handleOpenGetReadDateModal}>
|
||||||
<span>{lang('StatusHiddenShow')}</span>
|
<span>{oldLang('StatusHiddenShow')}</span>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -290,8 +302,8 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
|||||||
<span className={buildClassName(styles.status, 'status')} dir="auto">
|
<span className={buildClassName(styles.status, 'status')} dir="auto">
|
||||||
{
|
{
|
||||||
isChatChannel(chat!)
|
isChatChannel(chat!)
|
||||||
? lang('Subscribers', chat!.membersCount ?? 0, 'i')
|
? oldLang('Subscribers', chat!.membersCount ?? 0, 'i')
|
||||||
: lang('Members', chat!.membersCount ?? 0, 'i')
|
: oldLang('Members', chat!.membersCount ?? 0, 'i')
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
@ -304,7 +316,7 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={buildClassName('ProfileInfo')}
|
className={buildClassName('ProfileInfo')}
|
||||||
dir={lang.isRtl ? 'rtl' : undefined}
|
dir={oldLang.isRtl ? 'rtl' : undefined}
|
||||||
>
|
>
|
||||||
<div className={styles.photoWrapper}>
|
<div className={styles.photoWrapper}>
|
||||||
{renderPhotoTabs()}
|
{renderPhotoTabs()}
|
||||||
@ -315,7 +327,7 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className={styles.fallbackPhotoContents}>
|
<div className={styles.fallbackPhotoContents}>
|
||||||
{lang(profilePhotos.personalPhoto.isVideo ? 'UserInfo.CustomVideo' : 'UserInfo.CustomPhoto')}
|
{oldLang(profilePhotos.personalPhoto.isVideo ? 'UserInfo.CustomVideo' : 'UserInfo.CustomPhoto')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -333,7 +345,7 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
|||||||
size="mini"
|
size="mini"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{lang(profilePhotos.fallbackPhoto.isVideo ? 'UserInfo.PublicVideo' : 'UserInfo.PublicPhoto')}
|
{oldLang(profilePhotos.fallbackPhoto.isVideo ? 'UserInfo.PublicVideo' : 'UserInfo.PublicPhoto')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -344,24 +356,24 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
|
|||||||
{!isFirst && (
|
{!isFirst && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
dir={lang.isRtl ? 'rtl' : undefined}
|
dir={oldLang.isRtl ? 'rtl' : undefined}
|
||||||
className={buildClassName(styles.navigation, styles.navigation_prev)}
|
className={buildClassName(styles.navigation, styles.navigation_prev)}
|
||||||
aria-label={lang('AccDescrPrevious')}
|
aria-label={oldLang('AccDescrPrevious')}
|
||||||
onClick={selectPreviousMedia}
|
onClick={selectPreviousMedia}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!isLast && (
|
{!isLast && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
dir={lang.isRtl ? 'rtl' : undefined}
|
dir={oldLang.isRtl ? 'rtl' : undefined}
|
||||||
className={buildClassName(styles.navigation, styles.navigation_next)}
|
className={buildClassName(styles.navigation, styles.navigation_next)}
|
||||||
aria-label={lang('Next')}
|
aria-label={oldLang('Next')}
|
||||||
onClick={selectNextMedia}
|
onClick={selectNextMedia}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.info} dir={lang.isRtl ? 'rtl' : 'auto'}>
|
<div className={styles.info} dir={oldLang.isRtl ? 'rtl' : 'auto'}>
|
||||||
{(user || chat) && (
|
{(user || chat) && (
|
||||||
<FullNameTitle
|
<FullNameTitle
|
||||||
peer={(user || chat)!}
|
peer={(user || chat)!}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import {
|
|||||||
} from '../../global/helpers';
|
} from '../../global/helpers';
|
||||||
import { filterPeersByQuery } from '../../global/helpers/peers';
|
import { filterPeersByQuery } from '../../global/helpers/peers';
|
||||||
import {
|
import {
|
||||||
filterChatIdsByType, selectChat, selectChatFullInfo, selectUser,
|
filterChatIdsByType, selectChat, selectChatFullInfo, selectIsMonoforumAdmin, selectUser,
|
||||||
} from '../../global/selectors';
|
} from '../../global/selectors';
|
||||||
import { unique } from '../../util/iteratees';
|
import { unique } from '../../util/iteratees';
|
||||||
import sortChatIds from './helpers/sortChatIds';
|
import sortChatIds from './helpers/sortChatIds';
|
||||||
@ -77,9 +77,15 @@ const RecipientPicker: FC<OwnProps & StateProps> = ({
|
|||||||
const user = selectUser(global, id);
|
const user = selectUser(global, id);
|
||||||
if (user && !isDeletedUser(user)) return true;
|
if (user && !isDeletedUser(user)) return true;
|
||||||
|
|
||||||
const chatFullInfo = selectChatFullInfo(global, id);
|
if (!chat) return false;
|
||||||
|
|
||||||
return chat && (!chatFullInfo || getCanPostInChat(chat, undefined, undefined, chatFullInfo));
|
if (chat.isMonoforum && selectIsMonoforumAdmin(global, id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const chatFullInfo = selectChatFullInfo(global, id);
|
||||||
|
// TODO: Handle bulk check with API call
|
||||||
|
return !chatFullInfo || getCanPostInChat(chat, undefined, undefined, chatFullInfo);
|
||||||
});
|
});
|
||||||
|
|
||||||
const sorted = sortChatIds(
|
const sorted = sortChatIds(
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import type { MessageList } from '../../types';
|
|||||||
import { EMOJI_SIZE_MODAL, STICKER_SIZE_MODAL, TME_LINK_PREFIX } from '../../config';
|
import { EMOJI_SIZE_MODAL, STICKER_SIZE_MODAL, TME_LINK_PREFIX } from '../../config';
|
||||||
import { getAllowedAttachmentOptions, getCanPostInChat } from '../../global/helpers';
|
import { getAllowedAttachmentOptions, getCanPostInChat } from '../../global/helpers';
|
||||||
import {
|
import {
|
||||||
|
selectBot,
|
||||||
selectCanScheduleUntilOnline,
|
selectCanScheduleUntilOnline,
|
||||||
selectChat,
|
selectChat,
|
||||||
selectChatFullInfo,
|
selectChatFullInfo,
|
||||||
@ -261,7 +262,12 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const { chatId, threadId } = currentMessageList || {};
|
const { chatId, threadId } = currentMessageList || {};
|
||||||
const chat = chatId && selectChat(global, chatId);
|
const chat = chatId && selectChat(global, chatId);
|
||||||
const chatFullInfo = chatId ? selectChatFullInfo(global, chatId) : undefined;
|
const chatFullInfo = chatId ? selectChatFullInfo(global, chatId) : undefined;
|
||||||
const sendOptions = chat ? getAllowedAttachmentOptions(chat, chatFullInfo) : undefined;
|
const chatBot = chatId && selectBot(global, chatId);
|
||||||
|
const isSavedMessages = chatId ? selectIsChatWithSelf(global, chatId) : undefined;
|
||||||
|
|
||||||
|
const sendOptions = chat
|
||||||
|
? getAllowedAttachmentOptions(chat, chatFullInfo, Boolean(chatBot), isSavedMessages)
|
||||||
|
: undefined;
|
||||||
const threadInfo = chatId && threadId ? selectThreadInfo(global, chatId, threadId) : undefined;
|
const threadInfo = chatId && threadId ? selectThreadInfo(global, chatId, threadId) : undefined;
|
||||||
const isMessageThread = Boolean(!threadInfo?.isCommentsInfo && threadInfo?.fromChannelId);
|
const isMessageThread = Boolean(!threadInfo?.isCommentsInfo && threadInfo?.fromChannelId);
|
||||||
const topic = chatId && threadId ? selectTopic(global, chatId, threadId) : undefined;
|
const topic = chatId && threadId ? selectTopic(global, chatId, threadId) : undefined;
|
||||||
@ -269,7 +275,6 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
chat && threadId && getCanPostInChat(chat, topic, isMessageThread, chatFullInfo)
|
chat && threadId && getCanPostInChat(chat, topic, isMessageThread, chatFullInfo)
|
||||||
&& sendOptions?.canSendStickers,
|
&& sendOptions?.canSendStickers,
|
||||||
);
|
);
|
||||||
const isSavedMessages = Boolean(chatId) && selectIsChatWithSelf(global, chatId);
|
|
||||||
|
|
||||||
const stickerSetInfo = fromSticker ? fromSticker.stickerSetInfo
|
const stickerSetInfo = fromSticker ? fromSticker.stickerSetInfo
|
||||||
: stickerSetShortName ? { shortName: stickerSetShortName } : undefined;
|
: stickerSetShortName ? { shortName: stickerSetShortName } : undefined;
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import {
|
|||||||
getCanPostInChat, getGroupStatus, getUserStatus, isUserOnline,
|
getCanPostInChat, getGroupStatus, getUserStatus, isUserOnline,
|
||||||
} from '../../../global/helpers';
|
} from '../../../global/helpers';
|
||||||
import { isApiPeerChat } from '../../../global/helpers/peers';
|
import { isApiPeerChat } from '../../../global/helpers/peers';
|
||||||
import { selectPeer, selectTopics, selectUserStatus } from '../../../global/selectors';
|
import { selectMonoforumChannel, selectPeer, selectTopics, selectUserStatus } from '../../../global/selectors';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { REM } from '../helpers/mediaDimensions';
|
import { REM } from '../helpers/mediaDimensions';
|
||||||
import renderText from '../helpers/renderText';
|
import renderText from '../helpers/renderText';
|
||||||
@ -47,12 +47,12 @@ export type OwnProps = {
|
|||||||
searchPlaceholder: string;
|
searchPlaceholder: string;
|
||||||
search: string;
|
search: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
isLowStackPriority?: boolean;
|
||||||
loadMore?: NoneToVoidFunction;
|
loadMore?: NoneToVoidFunction;
|
||||||
onSearchChange: (search: string) => void;
|
onSearchChange: (search: string) => void;
|
||||||
onSelectChatOrUser: (chatOrUserId: string, threadId?: ThreadId) => void;
|
onSelectChatOrUser: (chatOrUserId: string, threadId?: ThreadId) => void;
|
||||||
onClose: NoneToVoidFunction;
|
onClose: NoneToVoidFunction;
|
||||||
onCloseAnimationEnd?: NoneToVoidFunction;
|
onCloseAnimationEnd?: NoneToVoidFunction;
|
||||||
isLowStackPriority?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const CHAT_LIST_SLIDE = 0;
|
const CHAT_LIST_SLIDE = 0;
|
||||||
@ -77,7 +77,7 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { loadTopics } = getActions();
|
const { loadTopics } = getActions();
|
||||||
|
|
||||||
const lang = useOldLang();
|
const oldLang = useOldLang();
|
||||||
const containerRef = useRef<HTMLDivElement>();
|
const containerRef = useRef<HTMLDivElement>();
|
||||||
const topicContainerRef = useRef<HTMLDivElement>();
|
const topicContainerRef = useRef<HTMLDivElement>();
|
||||||
const searchRef = useRef<HTMLInputElement>();
|
const searchRef = useRef<HTMLInputElement>();
|
||||||
@ -181,23 +181,28 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
|||||||
|
|
||||||
const renderChatItem = useCallback((id: string, index: number) => {
|
const renderChatItem = useCallback((id: string, index: number) => {
|
||||||
const global = getGlobal();
|
const global = getGlobal();
|
||||||
const peer = selectPeer(global, id);
|
let peer = selectPeer(global, id);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const monoforumChannel = selectMonoforumChannel(global, id);
|
||||||
|
if (monoforumChannel) {
|
||||||
|
peer = monoforumChannel;
|
||||||
|
}
|
||||||
|
|
||||||
const isSelf = peer && !isApiPeerChat(peer) ? peer.isSelf : undefined;
|
const isSelf = peer && !isApiPeerChat(peer) ? peer.isSelf : undefined;
|
||||||
|
|
||||||
function getSubtitle() {
|
function getSubtitle() {
|
||||||
if (!peer) return undefined;
|
if (!peer) return undefined;
|
||||||
if (peer.id === currentUserId) return [lang('SavedMessagesInfo')];
|
if (peer.id === currentUserId) return [oldLang('SavedMessagesInfo')];
|
||||||
if (isApiPeerChat(peer)) {
|
if (isApiPeerChat(peer)) {
|
||||||
return [getGroupStatus(lang, peer)];
|
return [getGroupStatus(oldLang, peer)];
|
||||||
}
|
}
|
||||||
|
|
||||||
const userStatus = selectUserStatus(global, peer.id);
|
const userStatus = selectUserStatus(global, peer.id);
|
||||||
return [
|
return [
|
||||||
getUserStatus(lang, peer, userStatus),
|
getUserStatus(oldLang, peer, userStatus),
|
||||||
buildClassName(isUserOnline(peer, userStatus, true) && 'online'),
|
buildClassName(isUserOnline(peer, userStatus, true) && 'online'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -208,10 +213,20 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
|||||||
<PickerItem
|
<PickerItem
|
||||||
key={id}
|
key={id}
|
||||||
className={ITEM_CLASS_NAME}
|
className={ITEM_CLASS_NAME}
|
||||||
title={<FullNameTitle peer={peer} isSavedMessages={isSelf} />}
|
title={(
|
||||||
|
<div className="title-wrapper">
|
||||||
|
<FullNameTitle
|
||||||
|
className="item-title"
|
||||||
|
peer={peer}
|
||||||
|
isMonoforum={Boolean(monoforumChannel)}
|
||||||
|
isSavedMessages={isSelf}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
avatarElement={(
|
avatarElement={(
|
||||||
<Avatar
|
<Avatar
|
||||||
peer={peer}
|
peer={peer}
|
||||||
|
asMessageBubble={Boolean(monoforumChannel)}
|
||||||
isSavedMessages={isSelf}
|
isSavedMessages={isSelf}
|
||||||
size="medium"
|
size="medium"
|
||||||
/>
|
/>
|
||||||
@ -224,13 +239,13 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
|||||||
onClick={() => handleClick(id)}
|
onClick={() => handleClick(id)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}, [currentUserId, lang, viewportOffset]);
|
}, [currentUserId, oldLang, viewportOffset]);
|
||||||
|
|
||||||
function renderTopicList() {
|
function renderTopicList() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="modal-header" dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className="modal-header" dir={oldLang.isRtl ? 'rtl' : undefined}>
|
||||||
<Button round color="translucent" size="smaller" ariaLabel={lang('Back')} onClick={handleHeaderBackClick}>
|
<Button round color="translucent" size="smaller" ariaLabel={oldLang('Back')} onClick={handleHeaderBackClick}>
|
||||||
<Icon name="arrow-left" />
|
<Icon name="arrow-left" />
|
||||||
</Button>
|
</Button>
|
||||||
<InputText
|
<InputText
|
||||||
@ -276,12 +291,12 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
|||||||
function renderChatList() {
|
function renderChatList() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="modal-header" dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className="modal-header" dir={oldLang.isRtl ? 'rtl' : undefined}>
|
||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="smaller"
|
||||||
ariaLabel={lang('Close')}
|
ariaLabel={oldLang('Close')}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
>
|
>
|
||||||
<Icon name="close" />
|
<Icon name="close" />
|
||||||
@ -308,7 +323,7 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
|||||||
{viewportIds.map(renderChatItem)}
|
{viewportIds.map(renderChatItem)}
|
||||||
</InfiniteScroll>
|
</InfiniteScroll>
|
||||||
) : viewportIds && !viewportIds.length ? (
|
) : viewportIds && !viewportIds.length ? (
|
||||||
<p className="no-results">{lang('lng_blocked_list_not_found')}</p>
|
<p className="no-results">{oldLang('lng_blocked_list_not_found')}</p>
|
||||||
) : (
|
) : (
|
||||||
<Loading />
|
<Loading />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -438,6 +438,11 @@
|
|||||||
.avatar-badge-wrapper .ChatBadge:not(.pinned).muted {
|
.avatar-badge-wrapper .ChatBadge:not(.pinned).muted {
|
||||||
background: var(--color-gray);
|
background: var(--color-gray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.monoforum-badge {
|
||||||
|
color: var(--color-chat-active);
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,6 +35,7 @@ import {
|
|||||||
selectIsCurrentUserFrozen,
|
selectIsCurrentUserFrozen,
|
||||||
selectIsForumPanelClosed,
|
selectIsForumPanelClosed,
|
||||||
selectIsForumPanelOpen,
|
selectIsForumPanelOpen,
|
||||||
|
selectMonoforumChannel,
|
||||||
selectNotifyDefaults,
|
selectNotifyDefaults,
|
||||||
selectNotifyException,
|
selectNotifyException,
|
||||||
selectOutgoingStatus,
|
selectOutgoingStatus,
|
||||||
@ -94,6 +95,7 @@ type OwnProps = {
|
|||||||
|
|
||||||
type StateProps = {
|
type StateProps = {
|
||||||
chat?: ApiChat;
|
chat?: ApiChat;
|
||||||
|
monoforumChannel?: ApiChat;
|
||||||
lastMessageStory?: ApiTypeStory;
|
lastMessageStory?: ApiTypeStory;
|
||||||
listedTopicIds?: number[];
|
listedTopicIds?: number[];
|
||||||
topics?: Record<number, ApiTopic>;
|
topics?: Record<number, ApiTopic>;
|
||||||
@ -128,6 +130,7 @@ const Chat: FC<OwnProps & StateProps> = ({
|
|||||||
topics,
|
topics,
|
||||||
observeIntersection,
|
observeIntersection,
|
||||||
chat,
|
chat,
|
||||||
|
monoforumChannel,
|
||||||
lastMessageStory,
|
lastMessageStory,
|
||||||
isMuted,
|
isMuted,
|
||||||
user,
|
user,
|
||||||
@ -177,7 +180,7 @@ const Chat: FC<OwnProps & StateProps> = ({
|
|||||||
const [shouldRenderMuteModal, markRenderMuteModal, unmarkRenderMuteModal] = useFlag();
|
const [shouldRenderMuteModal, markRenderMuteModal, unmarkRenderMuteModal] = useFlag();
|
||||||
const [shouldRenderChatFolderModal, markRenderChatFolderModal, unmarkRenderChatFolderModal] = useFlag();
|
const [shouldRenderChatFolderModal, markRenderChatFolderModal, unmarkRenderChatFolderModal] = useFlag();
|
||||||
|
|
||||||
const { isForum, isForumAsMessages } = chat || {};
|
const { isForum, isForumAsMessages, isMonoforum } = chat || {};
|
||||||
|
|
||||||
useEnsureMessage(isSavedDialog ? currentUserId : chatId, lastMessageId, lastMessage);
|
useEnsureMessage(isSavedDialog ? currentUserId : chatId, lastMessageId, lastMessage);
|
||||||
|
|
||||||
@ -355,11 +358,12 @@ const Chat: FC<OwnProps & StateProps> = ({
|
|||||||
>
|
>
|
||||||
<div className={buildClassName('status', 'status-clickable')}>
|
<div className={buildClassName('status', 'status-clickable')}>
|
||||||
<Avatar
|
<Avatar
|
||||||
peer={peer}
|
peer={isMonoforum ? monoforumChannel : peer}
|
||||||
isSavedMessages={user?.isSelf}
|
isSavedMessages={user?.isSelf}
|
||||||
isSavedDialog={isSavedDialog}
|
isSavedDialog={isSavedDialog}
|
||||||
size={isPreview ? 'medium' : 'large'}
|
size={isPreview ? 'medium' : 'large'}
|
||||||
withStory={!user?.isSelf}
|
asMessageBubble={isMonoforum}
|
||||||
|
withStory={!user?.isSelf && !isMonoforum}
|
||||||
withStoryGap={isAvatarOnlineShown || Boolean(chat.subscriptionUntil)}
|
withStoryGap={isAvatarOnlineShown || Boolean(chat.subscriptionUntil)}
|
||||||
storyViewerOrigin={StoryViewerOrigin.ChatList}
|
storyViewerOrigin={StoryViewerOrigin.ChatList}
|
||||||
storyViewerMode="single-peer"
|
storyViewerMode="single-peer"
|
||||||
@ -387,7 +391,9 @@ const Chat: FC<OwnProps & StateProps> = ({
|
|||||||
<div className="info">
|
<div className="info">
|
||||||
<div className="info-row">
|
<div className="info-row">
|
||||||
<FullNameTitle
|
<FullNameTitle
|
||||||
peer={peer}
|
peer={isMonoforum ? monoforumChannel! : peer}
|
||||||
|
isMonoforum={isMonoforum}
|
||||||
|
monoforumBadgeClassName="monoforum-badge"
|
||||||
withEmojiStatus
|
withEmojiStatus
|
||||||
isSavedMessages={chatId === user?.id && user?.isSelf}
|
isSavedMessages={chatId === user?.id && user?.isSelf}
|
||||||
isSavedDialog={isSavedDialog}
|
isSavedDialog={isSavedDialog}
|
||||||
@ -489,6 +495,8 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const lastMessageStory = storyData && selectPeerStory(global, storyData.peerId, storyData.id);
|
const lastMessageStory = storyData && selectPeerStory(global, storyData.peerId, storyData.id);
|
||||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||||
|
|
||||||
|
const monoforumChannel = selectMonoforumChannel(global, chatId);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
chat,
|
chat,
|
||||||
isMuted: getIsChatMuted(chat, selectNotifyDefaults(global), selectNotifyException(global, chat.id)),
|
isMuted: getIsChatMuted(chat, selectNotifyDefaults(global), selectNotifyException(global, chat.id)),
|
||||||
@ -515,6 +523,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
isSynced: global.isSynced,
|
isSynced: global.isSynced,
|
||||||
lastMessageStory,
|
lastMessageStory,
|
||||||
isAccountFrozen,
|
isAccountFrozen,
|
||||||
|
monoforumChannel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(Chat));
|
)(Chat));
|
||||||
|
|||||||
@ -74,6 +74,7 @@ interface StateProps {
|
|||||||
canLeave?: boolean;
|
canLeave?: boolean;
|
||||||
canEnterVoiceChat?: boolean;
|
canEnterVoiceChat?: boolean;
|
||||||
canCreateVoiceChat?: boolean;
|
canCreateVoiceChat?: boolean;
|
||||||
|
channelMonoforumId?: string;
|
||||||
pendingJoinRequests?: number;
|
pendingJoinRequests?: number;
|
||||||
shouldJoinToSend?: boolean;
|
shouldJoinToSend?: boolean;
|
||||||
shouldSendJoinRequest?: boolean;
|
shouldSendJoinRequest?: boolean;
|
||||||
@ -110,6 +111,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
|
|||||||
canLeave,
|
canLeave,
|
||||||
canEnterVoiceChat,
|
canEnterVoiceChat,
|
||||||
canCreateVoiceChat,
|
canCreateVoiceChat,
|
||||||
|
channelMonoforumId,
|
||||||
pendingJoinRequests,
|
pendingJoinRequests,
|
||||||
isRightColumnShown,
|
isRightColumnShown,
|
||||||
isForForum,
|
isForForum,
|
||||||
@ -451,6 +453,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
|
|||||||
pendingJoinRequests={pendingJoinRequests}
|
pendingJoinRequests={pendingJoinRequests}
|
||||||
onJoinRequestsClick={handleJoinRequestsClick}
|
onJoinRequestsClick={handleJoinRequestsClick}
|
||||||
withForumActions={isForForum}
|
withForumActions={isForForum}
|
||||||
|
channelMonoforumId={channelMonoforumId}
|
||||||
onSubscribeChannel={handleSubscribeClick}
|
onSubscribeChannel={handleSubscribeClick}
|
||||||
onSearchClick={handleSearchClick}
|
onSearchClick={handleSearchClick}
|
||||||
onAsMessagesClick={handleAsMessagesClick}
|
onAsMessagesClick={handleAsMessagesClick}
|
||||||
@ -499,7 +502,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const canStartBot = !canRestartBot && Boolean(selectIsChatBotNotStarted(global, chatId));
|
const canStartBot = !canRestartBot && Boolean(selectIsChatBotNotStarted(global, chatId));
|
||||||
const canUnblock = isUserBlocked && !bot;
|
const canUnblock = isUserBlocked && !bot;
|
||||||
const canSubscribe = Boolean(
|
const canSubscribe = Boolean(
|
||||||
(isMainThread || chat.isForum) && (isChannel || isSuperGroup) && chat.isNotJoined,
|
(isMainThread || chat.isForum) && (isChannel || isSuperGroup) && chat.isNotJoined && !chat.isMonoforum,
|
||||||
);
|
);
|
||||||
const canSearch = isMainThread || isDiscussionThread;
|
const canSearch = isMainThread || isDiscussionThread;
|
||||||
const canCall = ARE_CALLS_SUPPORTED && isUserId(chat.id) && !isChatWithSelf && !bot && !chat.isSupport
|
const canCall = ARE_CALLS_SUPPORTED && isUserId(chat.id) && !isChatWithSelf && !bot && !chat.isSupport
|
||||||
@ -508,12 +511,12 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const canLeave = isSavedDialog || (isMainThread && !canSubscribe);
|
const canLeave = isSavedDialog || (isMainThread && !canSubscribe);
|
||||||
const canEnterVoiceChat = ARE_CALLS_SUPPORTED && isMainThread && chat.isCallActive;
|
const canEnterVoiceChat = ARE_CALLS_SUPPORTED && isMainThread && chat.isCallActive;
|
||||||
const canCreateVoiceChat = ARE_CALLS_SUPPORTED && isMainThread && !chat.isCallActive
|
const canCreateVoiceChat = ARE_CALLS_SUPPORTED && isMainThread && !chat.isCallActive
|
||||||
&& (chat.adminRights?.manageCall || (chat.isCreator && isChatBasicGroup(chat)));
|
&& (chat.adminRights?.manageCall || (chat.isCreator && isChatBasicGroup(chat))) && !chat.isMonoforum;
|
||||||
const canViewStatistics = isMainThread && chatFullInfo?.canViewStatistics;
|
const canViewStatistics = isMainThread && chatFullInfo?.canViewStatistics;
|
||||||
const canViewMonetization = isMainThread && chatFullInfo?.canViewMonetization;
|
const canViewMonetization = isMainThread && chatFullInfo?.canViewMonetization;
|
||||||
const canViewBoosts = isMainThread
|
const canViewBoosts = isMainThread && !chat.isMonoforum
|
||||||
&& (isSuperGroup || isChannel) && (canViewStatistics || getHasAdminRight(chat, 'postStories'));
|
&& (isSuperGroup || isChannel) && (canViewStatistics || getHasAdminRight(chat, 'postStories'));
|
||||||
const canShowBoostModal = !canViewBoosts && (isSuperGroup || isChannel);
|
const canShowBoostModal = !canViewBoosts && (isSuperGroup || isChannel) && !chat.isMonoforum;
|
||||||
const pendingJoinRequests = isMainThread ? chatFullInfo?.requestsPending : undefined;
|
const pendingJoinRequests = isMainThread ? chatFullInfo?.requestsPending : undefined;
|
||||||
const shouldJoinToSend = Boolean(chat?.isNotJoined && chat.isJoinToSend);
|
const shouldJoinToSend = Boolean(chat?.isNotJoined && chat.isJoinToSend);
|
||||||
const shouldSendJoinRequest = Boolean(chat?.isNotJoined && chat.isJoinRequest);
|
const shouldSendJoinRequest = Boolean(chat?.isNotJoined && chat.isJoinRequest);
|
||||||
@ -523,6 +526,8 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const canTranslate = selectCanTranslateChat(global, chatId) && !fullInfo?.isTranslationDisabled;
|
const canTranslate = selectCanTranslateChat(global, chatId) && !fullInfo?.isTranslationDisabled;
|
||||||
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
const isAccountFrozen = selectIsCurrentUserFrozen(global);
|
||||||
|
|
||||||
|
const channelMonoforumId = isChatChannel(chat) ? chat.linkedMonoforumId : undefined;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
noMenu: false,
|
noMenu: false,
|
||||||
isChannel,
|
isChannel,
|
||||||
@ -552,6 +557,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
detectedChatLanguage: chat.detectedLanguage,
|
detectedChatLanguage: chat.detectedLanguage,
|
||||||
canUnblock,
|
canUnblock,
|
||||||
isAccountFrozen,
|
isAccountFrozen,
|
||||||
|
channelMonoforumId,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(HeaderActions));
|
)(HeaderActions));
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import {
|
|||||||
getCanManageTopic,
|
getCanManageTopic,
|
||||||
getHasAdminRight,
|
getHasAdminRight,
|
||||||
getIsSavedDialog,
|
getIsSavedDialog,
|
||||||
|
isChatAdmin,
|
||||||
isChatChannel,
|
isChatChannel,
|
||||||
isChatGroup,
|
isChatGroup,
|
||||||
isSystemBot,
|
isSystemBot,
|
||||||
@ -94,6 +95,7 @@ export type OwnProps = {
|
|||||||
canCreateVoiceChat?: boolean;
|
canCreateVoiceChat?: boolean;
|
||||||
pendingJoinRequests?: number;
|
pendingJoinRequests?: number;
|
||||||
canTranslate?: boolean;
|
canTranslate?: boolean;
|
||||||
|
channelMonoforumId?: string;
|
||||||
onSubscribeChannel: () => void;
|
onSubscribeChannel: () => void;
|
||||||
onSearchClick: () => void;
|
onSearchClick: () => void;
|
||||||
onAsMessagesClick: () => void;
|
onAsMessagesClick: () => void;
|
||||||
@ -176,14 +178,15 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
|||||||
isChatWithSelf,
|
isChatWithSelf,
|
||||||
savedDialog,
|
savedDialog,
|
||||||
canShowBoostModal,
|
canShowBoostModal,
|
||||||
|
disallowedGifts,
|
||||||
|
isAccountFrozen,
|
||||||
|
channelMonoforumId,
|
||||||
onJoinRequestsClick,
|
onJoinRequestsClick,
|
||||||
onSubscribeChannel,
|
onSubscribeChannel,
|
||||||
onSearchClick,
|
onSearchClick,
|
||||||
onAsMessagesClick,
|
onAsMessagesClick,
|
||||||
onClose,
|
onClose,
|
||||||
onCloseAnimationEnd,
|
onCloseAnimationEnd,
|
||||||
disallowedGifts,
|
|
||||||
isAccountFrozen,
|
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
updateChatMutedState,
|
updateChatMutedState,
|
||||||
@ -488,6 +491,11 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
|||||||
closeMenu();
|
closeMenu();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleSendChannelMessage = useLastCallback(() => {
|
||||||
|
openChat({ id: channelMonoforumId });
|
||||||
|
closeMenu();
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(disableScrolling, []);
|
useEffect(disableScrolling, []);
|
||||||
|
|
||||||
const botButtons = useMemo(() => {
|
const botButtons = useMemo(() => {
|
||||||
@ -585,6 +593,14 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
|||||||
<MenuSeparator />
|
<MenuSeparator />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
{channelMonoforumId && (
|
||||||
|
<MenuItem
|
||||||
|
icon="message"
|
||||||
|
onClick={handleSendChannelMessage}
|
||||||
|
>
|
||||||
|
{lang('ChannelSendMessage')}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
{isViewGroupInfoShown && (
|
{isViewGroupInfoShown && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="info"
|
icon="info"
|
||||||
@ -835,7 +851,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const isMainThread = threadId === MAIN_THREAD_ID;
|
const isMainThread = threadId === MAIN_THREAD_ID;
|
||||||
const isChatWithSelf = selectIsChatWithSelf(global, chatId);
|
const isChatWithSelf = selectIsChatWithSelf(global, chatId);
|
||||||
const { chatId: currentChatId, threadId: currentThreadId } = selectCurrentMessageList(global) || {};
|
const { chatId: currentChatId, threadId: currentThreadId } = selectCurrentMessageList(global) || {};
|
||||||
const canReportChat = isMainThread && !user && (isChatChannel(chat) || isChatGroup(chat));
|
const canReportChat = isMainThread && !user && (isChatChannel(chat) || isChatGroup(chat)) && !isChatAdmin(chat);
|
||||||
|
|
||||||
const chatBot = !isSystemBot(chatId) ? selectBot(global, chatId) : undefined;
|
const chatBot = !isSystemBot(chatId) ? selectBot(global, chatId) : undefined;
|
||||||
const userFullInfo = isPrivate ? selectUserFullInfo(global, chatId) : undefined;
|
const userFullInfo = isPrivate ? selectUserFullInfo(global, chatId) : undefined;
|
||||||
|
|||||||
@ -28,6 +28,7 @@ import {
|
|||||||
isAnonymousForwardsChat,
|
isAnonymousForwardsChat,
|
||||||
isChatChannel,
|
isChatChannel,
|
||||||
isChatGroup,
|
isChatGroup,
|
||||||
|
isChatMonoforum,
|
||||||
isSystemBot,
|
isSystemBot,
|
||||||
} from '../../global/helpers';
|
} from '../../global/helpers';
|
||||||
import {
|
import {
|
||||||
@ -48,6 +49,7 @@ import {
|
|||||||
selectIsInSelectMode,
|
selectIsInSelectMode,
|
||||||
selectIsViewportNewest,
|
selectIsViewportNewest,
|
||||||
selectLastScrollOffset,
|
selectLastScrollOffset,
|
||||||
|
selectMonoforumChannel,
|
||||||
selectPerformanceSettingsValue,
|
selectPerformanceSettingsValue,
|
||||||
selectScrollOffset,
|
selectScrollOffset,
|
||||||
selectTabState,
|
selectTabState,
|
||||||
@ -107,6 +109,7 @@ type StateProps = {
|
|||||||
isChatLoaded?: boolean;
|
isChatLoaded?: boolean;
|
||||||
isChannelChat?: boolean;
|
isChannelChat?: boolean;
|
||||||
isGroupChat?: boolean;
|
isGroupChat?: boolean;
|
||||||
|
isChatMonoforum?: boolean;
|
||||||
isChatWithSelf?: boolean;
|
isChatWithSelf?: boolean;
|
||||||
isSystemBotChat?: boolean;
|
isSystemBotChat?: boolean;
|
||||||
isAnonymousForwards?: boolean;
|
isAnonymousForwards?: boolean;
|
||||||
@ -139,6 +142,7 @@ type StateProps = {
|
|||||||
isChatProtected?: boolean;
|
isChatProtected?: boolean;
|
||||||
hasCustomGreeting?: boolean;
|
hasCustomGreeting?: boolean;
|
||||||
isAppConfigLoaded?: boolean;
|
isAppConfigLoaded?: boolean;
|
||||||
|
monoforumChannelId?: string;
|
||||||
canTranslate?: boolean;
|
canTranslate?: boolean;
|
||||||
translationLanguage?: string;
|
translationLanguage?: string;
|
||||||
shouldAutoTranslate?: boolean;
|
shouldAutoTranslate?: boolean;
|
||||||
@ -169,6 +173,7 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
|||||||
isChannelWithAvatars,
|
isChannelWithAvatars,
|
||||||
canPost,
|
canPost,
|
||||||
isSynced,
|
isSynced,
|
||||||
|
isChatMonoforum,
|
||||||
isReady,
|
isReady,
|
||||||
isChatWithSelf,
|
isChatWithSelf,
|
||||||
isSystemBotChat,
|
isSystemBotChat,
|
||||||
@ -203,6 +208,7 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
|||||||
isChatProtected,
|
isChatProtected,
|
||||||
isAccountFrozen,
|
isAccountFrozen,
|
||||||
hasCustomGreeting,
|
hasCustomGreeting,
|
||||||
|
monoforumChannelId,
|
||||||
isAppConfigLoaded,
|
isAppConfigLoaded,
|
||||||
canTranslate,
|
canTranslate,
|
||||||
translationLanguage,
|
translationLanguage,
|
||||||
@ -695,7 +701,7 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
|||||||
isChatProtected && 'hide-on-print',
|
isChatProtected && 'hide-on-print',
|
||||||
);
|
);
|
||||||
|
|
||||||
const hasMessages = (messageIds && messageGroups) || lastMessage;
|
const hasMessages = Boolean((messageIds && messageGroups) || lastMessage);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (hasMessages) return;
|
if (hasMessages) return;
|
||||||
@ -716,12 +722,12 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
|||||||
{restrictionReason ? restrictionReason.text : `This is a private ${isChannelChat ? 'channel' : 'chat'}`}
|
{restrictionReason ? restrictionReason.text : `This is a private ${isChannelChat ? 'channel' : 'chat'}`}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
) : paidMessagesStars && isPrivate && !hasMessages && !hasCustomGreeting ? (
|
) : paidMessagesStars && !hasMessages && !hasCustomGreeting ? (
|
||||||
<RequirementToContactMessage paidMessagesStars={paidMessagesStars} userId={chatId} />
|
<RequirementToContactMessage paidMessagesStars={paidMessagesStars} peerId={monoforumChannelId || chatId} />
|
||||||
) : isContactRequirePremium && !hasMessages ? (
|
) : isContactRequirePremium && !hasMessages ? (
|
||||||
<RequirementToContactMessage userId={chatId} />
|
<RequirementToContactMessage peerId={chatId} />
|
||||||
) : (isBot || isNonContact) && !hasMessages ? (
|
) : (isBot || isNonContact) && !hasMessages ? (
|
||||||
<MessageListAccountInfo chatId={chatId} />
|
<MessageListAccountInfo chatId={chatId} hasMessages={hasMessages} />
|
||||||
) : shouldRenderGreeting ? (
|
) : shouldRenderGreeting ? (
|
||||||
<ContactGreeting key={chatId} userId={chatId} />
|
<ContactGreeting key={chatId} userId={chatId} />
|
||||||
) : messageIds && (!messageGroups || isGroupChatJustCreated || isEmptyTopic) ? (
|
) : messageIds && (!messageGroups || isGroupChatJustCreated || isEmptyTopic) ? (
|
||||||
@ -738,6 +744,7 @@ const MessageList: FC<OwnProps & StateProps> = ({
|
|||||||
chatId={chatId}
|
chatId={chatId}
|
||||||
isComments={isComments}
|
isComments={isComments}
|
||||||
isChannelChat={isChannelChat}
|
isChannelChat={isChannelChat}
|
||||||
|
isChatMonoforum={isChatMonoforum}
|
||||||
isSavedDialog={isSavedDialog}
|
isSavedDialog={isSavedDialog}
|
||||||
messageIds={messageIds || [lastMessage!.id]}
|
messageIds={messageIds || [lastMessage!.id]}
|
||||||
messageGroups={messageGroups || groupMessages([lastMessage!])}
|
messageGroups={messageGroups || groupMessages([lastMessage!])}
|
||||||
@ -820,6 +827,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const hasCustomGreeting = Boolean(userFullInfo?.businessIntro);
|
const hasCustomGreeting = Boolean(userFullInfo?.businessIntro);
|
||||||
const isAppConfigLoaded = global.isAppConfigLoaded;
|
const isAppConfigLoaded = global.isAppConfigLoaded;
|
||||||
|
|
||||||
|
const monoforumChannelId = selectMonoforumChannel(global, chatId)?.id;
|
||||||
const canTranslate = selectCanTranslateChat(global, chatId) && !chatFullInfo?.isTranslationDisabled;
|
const canTranslate = selectCanTranslateChat(global, chatId) && !chatFullInfo?.isTranslationDisabled;
|
||||||
const shouldAutoTranslate = chat?.hasAutoTranslation;
|
const shouldAutoTranslate = chat?.hasAutoTranslation;
|
||||||
const translationLanguage = selectTranslationLanguage(global);
|
const translationLanguage = selectTranslationLanguage(global);
|
||||||
@ -830,6 +838,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
isRestricted,
|
isRestricted,
|
||||||
restrictionReason,
|
restrictionReason,
|
||||||
isChannelChat: isChatChannel(chat),
|
isChannelChat: isChatChannel(chat),
|
||||||
|
isChatMonoforum: isChatMonoforum(chat),
|
||||||
isGroupChat: isChatGroup(chat),
|
isGroupChat: isChatGroup(chat),
|
||||||
isChannelWithAvatars: chat.areProfilesShown,
|
isChannelWithAvatars: chat.areProfilesShown,
|
||||||
isCreator: chat.isCreator,
|
isCreator: chat.isCreator,
|
||||||
@ -860,6 +869,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
isAccountFrozen,
|
isAccountFrozen,
|
||||||
hasCustomGreeting,
|
hasCustomGreeting,
|
||||||
isAppConfigLoaded,
|
isAppConfigLoaded,
|
||||||
|
monoforumChannelId,
|
||||||
canTranslate,
|
canTranslate,
|
||||||
translationLanguage,
|
translationLanguage,
|
||||||
shouldAutoTranslate,
|
shouldAutoTranslate,
|
||||||
|
|||||||
@ -46,7 +46,7 @@ import styles from './MessageListAccountInfo.module.scss';
|
|||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
chatId: string;
|
chatId: string;
|
||||||
isInMessageList?: boolean;
|
hasMessages?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps = {
|
||||||
@ -66,6 +66,7 @@ const MessageListAccountInfo: FC<OwnProps & StateProps> = ({
|
|||||||
phoneCodeList,
|
phoneCodeList,
|
||||||
commonChats,
|
commonChats,
|
||||||
userFullInfo,
|
userFullInfo,
|
||||||
|
hasMessages,
|
||||||
}) => {
|
}) => {
|
||||||
const { loadCommonChats, openChatWithInfo } = getActions();
|
const { loadCommonChats, openChatWithInfo } = getActions();
|
||||||
const oldLang = useOldLang();
|
const oldLang = useOldLang();
|
||||||
@ -170,7 +171,9 @@ const MessageListAccountInfo: FC<OwnProps & StateProps> = ({
|
|||||||
return (
|
return (
|
||||||
<div className={buildClassName(styles.root, 'empty')}>
|
<div className={buildClassName(styles.root, 'empty')}>
|
||||||
{isLoadingFullUser && isChatInfoEmpty && <span>{oldLang('Loading')}</span>}
|
{isLoadingFullUser && isChatInfoEmpty && <span>{oldLang('Loading')}</span>}
|
||||||
{(isBotInfoEmpty && isChatInfoEmpty) && !isLoadingFullUser && <span>{oldLang('NoMessages')}</span>}
|
{(isBotInfoEmpty && isChatInfoEmpty) && !isLoadingFullUser && !hasMessages && (
|
||||||
|
<span>{oldLang('NoMessages')}</span>
|
||||||
|
)}
|
||||||
{botInfo && (
|
{botInfo && (
|
||||||
<div
|
<div
|
||||||
className={buildClassName(styles.chatInfo, styles.botBackground)}
|
className={buildClassName(styles.chatInfo, styles.botBackground)}
|
||||||
|
|||||||
@ -50,6 +50,7 @@ interface OwnProps {
|
|||||||
isUnread: boolean;
|
isUnread: boolean;
|
||||||
withUsers: boolean;
|
withUsers: boolean;
|
||||||
isChannelChat: boolean | undefined;
|
isChannelChat: boolean | undefined;
|
||||||
|
isChatMonoforum?: boolean;
|
||||||
isEmptyThread?: boolean;
|
isEmptyThread?: boolean;
|
||||||
isComments?: boolean;
|
isComments?: boolean;
|
||||||
noAvatars: boolean;
|
noAvatars: boolean;
|
||||||
@ -87,6 +88,7 @@ const MessageListContent: FC<OwnProps> = ({
|
|||||||
isEmptyThread,
|
isEmptyThread,
|
||||||
withUsers,
|
withUsers,
|
||||||
isChannelChat,
|
isChannelChat,
|
||||||
|
isChatMonoforum,
|
||||||
noAvatars,
|
noAvatars,
|
||||||
containerRef,
|
containerRef,
|
||||||
anchorIdRef,
|
anchorIdRef,
|
||||||
@ -261,7 +263,7 @@ const MessageListContent: FC<OwnProps> = ({
|
|||||||
// Service notifications saved in cache in previous versions may share the same `previousLocalId`
|
// Service notifications saved in cache in previous versions may share the same `previousLocalId`
|
||||||
const key = isServiceNotificationMessage(message) ? `${message.date}_${originalId}` : originalId;
|
const key = isServiceNotificationMessage(message) ? `${message.date}_${originalId}` : originalId;
|
||||||
|
|
||||||
const noComments = hasLinkedChat === false || !isChannelChat;
|
const noComments = hasLinkedChat === false || !isChannelChat || Boolean(isChatMonoforum);
|
||||||
|
|
||||||
return compact([
|
return compact([
|
||||||
message.id === memoUnreadDividerBeforeIdRef.current && unreadDivider,
|
message.id === memoUnreadDividerBeforeIdRef.current && unreadDivider,
|
||||||
@ -377,7 +379,7 @@ const MessageListContent: FC<OwnProps> = ({
|
|||||||
<div className="messages-container" teactFastList>
|
<div className="messages-container" teactFastList>
|
||||||
{withHistoryTriggers && <div ref={backwardsTriggerRef} key="backwards-trigger" className="backwards-trigger" />}
|
{withHistoryTriggers && <div ref={backwardsTriggerRef} key="backwards-trigger" className="backwards-trigger" />}
|
||||||
{shouldRenderAccountInfo
|
{shouldRenderAccountInfo
|
||||||
&& <MessageListAccountInfo key={`account_info_${chatId}`} chatId={chatId} />}
|
&& <MessageListAccountInfo key={`account_info_${chatId}`} chatId={chatId} hasMessages />}
|
||||||
{dateGroups.flat()}
|
{dateGroups.flat()}
|
||||||
{withHistoryTriggers && (
|
{withHistoryTriggers && (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -51,6 +51,7 @@ import {
|
|||||||
selectIsChatBotNotStarted,
|
selectIsChatBotNotStarted,
|
||||||
selectIsCurrentUserFrozen,
|
selectIsCurrentUserFrozen,
|
||||||
selectIsInSelectMode,
|
selectIsInSelectMode,
|
||||||
|
selectIsMonoforumAdmin,
|
||||||
selectIsRightColumnShown,
|
selectIsRightColumnShown,
|
||||||
selectIsUserBlocked,
|
selectIsUserBlocked,
|
||||||
selectPeerPaidMessagesStars,
|
selectPeerPaidMessagesStars,
|
||||||
@ -76,6 +77,7 @@ import useAppLayout from '../../hooks/useAppLayout';
|
|||||||
import useCustomBackground from '../../hooks/useCustomBackground';
|
import useCustomBackground from '../../hooks/useCustomBackground';
|
||||||
import useForceUpdate from '../../hooks/useForceUpdate';
|
import useForceUpdate from '../../hooks/useForceUpdate';
|
||||||
import useHistoryBack from '../../hooks/useHistoryBack';
|
import useHistoryBack from '../../hooks/useHistoryBack';
|
||||||
|
import useLang from '../../hooks/useLang';
|
||||||
import useLastCallback from '../../hooks/useLastCallback';
|
import useLastCallback from '../../hooks/useLastCallback';
|
||||||
import useOldLang from '../../hooks/useOldLang';
|
import useOldLang from '../../hooks/useOldLang';
|
||||||
import usePrevDuringAnimation from '../../hooks/usePrevDuringAnimation';
|
import usePrevDuringAnimation from '../../hooks/usePrevDuringAnimation';
|
||||||
@ -163,6 +165,7 @@ type StateProps = {
|
|||||||
paidMessagesStars?: number;
|
paidMessagesStars?: number;
|
||||||
isAccountFrozen?: boolean;
|
isAccountFrozen?: boolean;
|
||||||
freezeAppealChat?: ApiChat;
|
freezeAppealChat?: ApiChat;
|
||||||
|
shouldBlockSendInMonoforum?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
function isImage(item: DataTransferItem) {
|
function isImage(item: DataTransferItem) {
|
||||||
@ -226,6 +229,7 @@ function MiddleColumn({
|
|||||||
paidMessagesStars,
|
paidMessagesStars,
|
||||||
isAccountFrozen,
|
isAccountFrozen,
|
||||||
freezeAppealChat,
|
freezeAppealChat,
|
||||||
|
shouldBlockSendInMonoforum,
|
||||||
}: OwnProps & StateProps) {
|
}: OwnProps & StateProps) {
|
||||||
const {
|
const {
|
||||||
openChat,
|
openChat,
|
||||||
@ -247,7 +251,8 @@ function MiddleColumn({
|
|||||||
const { width: windowWidth } = useWindowSize();
|
const { width: windowWidth } = useWindowSize();
|
||||||
const { isTablet, isDesktop } = useAppLayout();
|
const { isTablet, isDesktop } = useAppLayout();
|
||||||
|
|
||||||
const lang = useOldLang();
|
const oldLang = useOldLang();
|
||||||
|
const lang = useLang();
|
||||||
const [dropAreaState, setDropAreaState] = useState(DropAreaState.None);
|
const [dropAreaState, setDropAreaState] = useState(DropAreaState.None);
|
||||||
const [isScrollDownNeeded, setIsScrollDownShown] = useState(false);
|
const [isScrollDownNeeded, setIsScrollDownShown] = useState(false);
|
||||||
const isScrollDownShown = isScrollDownNeeded && (!isMobile || !hasActiveMiddleSearch);
|
const isScrollDownShown = isScrollDownNeeded && (!isMobile || !hasActiveMiddleSearch);
|
||||||
@ -412,7 +417,8 @@ function MiddleColumn({
|
|||||||
joinChannel({ chatId: chatId! });
|
joinChannel({ chatId: chatId! });
|
||||||
if (renderingShouldSendJoinRequest) {
|
if (renderingShouldSendJoinRequest) {
|
||||||
showNotification({
|
showNotification({
|
||||||
message: isChannel ? lang('RequestToJoinChannelSentDescription') : lang('RequestToJoinGroupSentDescription'),
|
message: isChannel
|
||||||
|
? oldLang('RequestToJoinChannelSentDescription') : oldLang('RequestToJoinGroupSentDescription'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -451,14 +457,17 @@ function MiddleColumn({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const messageSendingRestrictionReason = getMessageSendingRestrictionReason(
|
const messageSendingRestrictionReason = getMessageSendingRestrictionReason(
|
||||||
lang, currentUserBannedRights, defaultBannedRights,
|
oldLang, currentUserBannedRights, defaultBannedRights,
|
||||||
|
);
|
||||||
|
const forumComposerPlaceholder = getForumComposerPlaceholder(
|
||||||
|
oldLang, chat, threadId, topics, Boolean(draftReplyInfo),
|
||||||
);
|
);
|
||||||
const forumComposerPlaceholder = getForumComposerPlaceholder(lang, chat, threadId, topics, Boolean(draftReplyInfo));
|
|
||||||
|
|
||||||
const composerRestrictionMessage = messageSendingRestrictionReason
|
const composerRestrictionMessage = messageSendingRestrictionReason
|
||||||
?? forumComposerPlaceholder
|
|| forumComposerPlaceholder
|
||||||
?? (isContactRequirePremium ? <PremiumRequiredPlaceholder userId={chatId!} /> : undefined)
|
|| (shouldBlockSendInMonoforum ? lang('MonoforumComposerPlaceholder') : undefined)
|
||||||
?? (isAccountFrozen && freezeAppealChat?.id !== chatId ? <FrozenAccountPlaceholder /> : undefined);
|
|| (isContactRequirePremium ? <PremiumRequiredPlaceholder userId={chatId!} /> : undefined)
|
||||||
|
|| (isAccountFrozen && freezeAppealChat?.id !== chatId ? <FrozenAccountPlaceholder /> : undefined);
|
||||||
|
|
||||||
// CSS Variables calculation doesn't work properly with transforms, so we calculate transform values in JS
|
// CSS Variables calculation doesn't work properly with transforms, so we calculate transform values in JS
|
||||||
const {
|
const {
|
||||||
@ -587,7 +596,7 @@ function MiddleColumn({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{isPinnedMessageList && canUnpin && (
|
{isPinnedMessageList && canUnpin && (
|
||||||
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className="middle-column-footer-button-container" dir={oldLang.isRtl ? 'rtl' : undefined}>
|
||||||
<Button
|
<Button
|
||||||
size="tiny"
|
size="tiny"
|
||||||
fluid
|
fluid
|
||||||
@ -596,12 +605,12 @@ function MiddleColumn({
|
|||||||
onClick={handleOpenUnpinModal}
|
onClick={handleOpenUnpinModal}
|
||||||
>
|
>
|
||||||
<Icon name="unpin" />
|
<Icon name="unpin" />
|
||||||
<span>{lang('Chat.Pinned.UnpinAll', pinnedMessagesCount, 'i')}</span>
|
<span>{oldLang('Chat.Pinned.UnpinAll', pinnedMessagesCount, 'i')}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{canShowOpenChatButton && (
|
{canShowOpenChatButton && (
|
||||||
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className="middle-column-footer-button-container" dir={oldLang.isRtl ? 'rtl' : undefined}>
|
||||||
<Button
|
<Button
|
||||||
size="tiny"
|
size="tiny"
|
||||||
fluid
|
fluid
|
||||||
@ -609,7 +618,7 @@ function MiddleColumn({
|
|||||||
className="composer-button open-chat-button"
|
className="composer-button open-chat-button"
|
||||||
onClick={handleOpenChatFromSaved}
|
onClick={handleOpenChatFromSaved}
|
||||||
>
|
>
|
||||||
<span>{lang('SavedOpenChat')}</span>
|
<span>{oldLang('SavedOpenChat')}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -625,7 +634,7 @@ function MiddleColumn({
|
|||||||
{(
|
{(
|
||||||
isMobile && (renderingCanSubscribe || (renderingShouldJoinToSend && !renderingShouldSendJoinRequest))
|
isMobile && (renderingCanSubscribe || (renderingShouldJoinToSend && !renderingShouldSendJoinRequest))
|
||||||
) && (
|
) && (
|
||||||
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className="middle-column-footer-button-container" dir={oldLang.isRtl ? 'rtl' : undefined}>
|
||||||
<Button
|
<Button
|
||||||
size="tiny"
|
size="tiny"
|
||||||
fluid
|
fluid
|
||||||
@ -633,12 +642,12 @@ function MiddleColumn({
|
|||||||
className="composer-button join-subscribe-button"
|
className="composer-button join-subscribe-button"
|
||||||
onClick={handleSubscribeClick}
|
onClick={handleSubscribeClick}
|
||||||
>
|
>
|
||||||
{lang(renderingIsChannel ? 'ProfileJoinChannel' : 'ProfileJoinGroup')}
|
{oldLang(renderingIsChannel ? 'ProfileJoinChannel' : 'ProfileJoinGroup')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{isMobile && renderingShouldSendJoinRequest && (
|
{isMobile && renderingShouldSendJoinRequest && (
|
||||||
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className="middle-column-footer-button-container" dir={oldLang.isRtl ? 'rtl' : undefined}>
|
||||||
<Button
|
<Button
|
||||||
size="tiny"
|
size="tiny"
|
||||||
fluid
|
fluid
|
||||||
@ -646,12 +655,12 @@ function MiddleColumn({
|
|||||||
className="composer-button join-subscribe-button"
|
className="composer-button join-subscribe-button"
|
||||||
onClick={handleSubscribeClick}
|
onClick={handleSubscribeClick}
|
||||||
>
|
>
|
||||||
{lang('ChannelJoinRequest')}
|
{oldLang('ChannelJoinRequest')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{isMobile && renderingCanStartBot && (
|
{isMobile && renderingCanStartBot && (
|
||||||
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className="middle-column-footer-button-container" dir={oldLang.isRtl ? 'rtl' : undefined}>
|
||||||
<Button
|
<Button
|
||||||
size="tiny"
|
size="tiny"
|
||||||
fluid
|
fluid
|
||||||
@ -659,12 +668,12 @@ function MiddleColumn({
|
|||||||
className="composer-button join-subscribe-button"
|
className="composer-button join-subscribe-button"
|
||||||
onClick={handleStartBot}
|
onClick={handleStartBot}
|
||||||
>
|
>
|
||||||
{lang('BotStart')}
|
{oldLang('BotStart')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{isMobile && renderingCanRestartBot && (
|
{isMobile && renderingCanRestartBot && (
|
||||||
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className="middle-column-footer-button-container" dir={oldLang.isRtl ? 'rtl' : undefined}>
|
||||||
<Button
|
<Button
|
||||||
size="tiny"
|
size="tiny"
|
||||||
fluid
|
fluid
|
||||||
@ -672,12 +681,12 @@ function MiddleColumn({
|
|||||||
className="composer-button join-subscribe-button"
|
className="composer-button join-subscribe-button"
|
||||||
onClick={handleRestartBot}
|
onClick={handleRestartBot}
|
||||||
>
|
>
|
||||||
{lang('BotRestart')}
|
{oldLang('BotRestart')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{isMobile && renderingCanUnblock && (
|
{isMobile && renderingCanUnblock && (
|
||||||
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className="middle-column-footer-button-container" dir={oldLang.isRtl ? 'rtl' : undefined}>
|
||||||
<Button
|
<Button
|
||||||
size="tiny"
|
size="tiny"
|
||||||
fluid
|
fluid
|
||||||
@ -685,7 +694,7 @@ function MiddleColumn({
|
|||||||
className="composer-button join-subscribe-button"
|
className="composer-button join-subscribe-button"
|
||||||
onClick={handleUnblock}
|
onClick={handleUnblock}
|
||||||
>
|
>
|
||||||
{lang('Unblock')}
|
{oldLang('Unblock')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -788,7 +797,8 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const isMainThread = messageListType === 'thread' && threadId === MAIN_THREAD_ID;
|
const isMainThread = messageListType === 'thread' && threadId === MAIN_THREAD_ID;
|
||||||
const isChannel = Boolean(chat && isChatChannel(chat));
|
const isChannel = Boolean(chat && isChatChannel(chat));
|
||||||
const canSubscribe = Boolean(
|
const canSubscribe = Boolean(
|
||||||
chat && isMainThread && (isChannel || isChatSuperGroup(chat)) && chat.isNotJoined && !chat.joinRequests,
|
chat && isMainThread && (isChannel || isChatSuperGroup(chat)) && chat.isNotJoined && !chat.joinRequests
|
||||||
|
&& !chat.isMonoforum,
|
||||||
);
|
);
|
||||||
const shouldJoinToSend = Boolean(chat?.isNotJoined && chat.isJoinToSend);
|
const shouldJoinToSend = Boolean(chat?.isNotJoined && chat.isJoinToSend);
|
||||||
const shouldSendJoinRequest = Boolean(chat?.isNotJoined && chat.isJoinRequest);
|
const shouldSendJoinRequest = Boolean(chat?.isNotJoined && chat.isJoinRequest);
|
||||||
@ -803,6 +813,8 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const shouldBlockSendInForum = chat?.isForum
|
const shouldBlockSendInForum = chat?.isForum
|
||||||
? threadId === MAIN_THREAD_ID && !draftReplyInfo && (selectTopic(global, chatId, GENERAL_TOPIC_ID)?.isClosed)
|
? threadId === MAIN_THREAD_ID && !draftReplyInfo && (selectTopic(global, chatId, GENERAL_TOPIC_ID)?.isClosed)
|
||||||
: false;
|
: false;
|
||||||
|
const isMonoforumAdmin = selectIsMonoforumAdmin(global, chatId);
|
||||||
|
const shouldBlockSendInMonoforum = Boolean(chat?.isMonoforum && !draftReplyInfo && isMonoforumAdmin);
|
||||||
const topics = selectTopics(global, chatId);
|
const topics = selectTopics(global, chatId);
|
||||||
|
|
||||||
const isSavedDialog = getIsSavedDialog(chatId, threadId, global.currentUserId);
|
const isSavedDialog = getIsSavedDialog(chatId, threadId, global.currentUserId);
|
||||||
@ -840,6 +852,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
&& !isBotNotStarted
|
&& !isBotNotStarted
|
||||||
&& !(shouldJoinToSend && chat?.isNotJoined)
|
&& !(shouldJoinToSend && chat?.isNotJoined)
|
||||||
&& !shouldBlockSendInForum
|
&& !shouldBlockSendInForum
|
||||||
|
&& !shouldBlockSendInMonoforum
|
||||||
&& !isSavedDialog
|
&& !isSavedDialog
|
||||||
&& (!isAccountFrozen || freezeAppealChat?.id === chatId),
|
&& (!isAccountFrozen || freezeAppealChat?.id === chatId),
|
||||||
isPinnedMessageList,
|
isPinnedMessageList,
|
||||||
@ -864,6 +877,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
paidMessagesStars,
|
paidMessagesStars,
|
||||||
isAccountFrozen,
|
isAccountFrozen,
|
||||||
freezeAppealChat,
|
freezeAppealChat,
|
||||||
|
shouldBlockSendInMonoforum,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(MiddleColumn));
|
)(MiddleColumn));
|
||||||
|
|||||||
@ -261,6 +261,8 @@ const MiddleHeader: FC<OwnProps & StateProps> = ({
|
|||||||
const savedMessagesStatus = isSavedDialog ? lang('SavedMessages') : undefined;
|
const savedMessagesStatus = isSavedDialog ? lang('SavedMessages') : undefined;
|
||||||
|
|
||||||
const realChatId = isSavedDialog ? String(threadId) : chatId;
|
const realChatId = isSavedDialog ? String(threadId) : chatId;
|
||||||
|
|
||||||
|
const displayChatId = chat?.isMonoforum ? chat.linkedMonoforumId! : realChatId;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{(isLeftColumnHideable || currentTransitionKey > 0) && renderBackButton(shouldShowCloseButton, !isSavedDialog)}
|
{(isLeftColumnHideable || currentTransitionKey > 0) && renderBackButton(shouldShowCloseButton, !isSavedDialog)}
|
||||||
@ -272,10 +274,10 @@ const MiddleHeader: FC<OwnProps & StateProps> = ({
|
|||||||
onTouchStart={handleLongPressTouchStart}
|
onTouchStart={handleLongPressTouchStart}
|
||||||
onTouchEnd={handleLongPressTouchEnd}
|
onTouchEnd={handleLongPressTouchEnd}
|
||||||
>
|
>
|
||||||
{isUserId(realChatId) ? (
|
{isUserId(displayChatId) ? (
|
||||||
<PrivateChatInfo
|
<PrivateChatInfo
|
||||||
key={realChatId}
|
key={displayChatId}
|
||||||
userId={realChatId}
|
userId={displayChatId}
|
||||||
typingStatus={typingStatus}
|
typingStatus={typingStatus}
|
||||||
status={connectionStatusText || savedMessagesStatus}
|
status={connectionStatusText || savedMessagesStatus}
|
||||||
withDots={Boolean(connectionStatusText)}
|
withDots={Boolean(connectionStatusText)}
|
||||||
@ -291,10 +293,11 @@ const MiddleHeader: FC<OwnProps & StateProps> = ({
|
|||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<GroupChatInfo
|
<GroupChatInfo
|
||||||
key={realChatId}
|
key={displayChatId}
|
||||||
chatId={realChatId}
|
chatId={displayChatId}
|
||||||
threadId={!isSavedDialog ? threadId : undefined}
|
threadId={!isSavedDialog ? threadId : undefined}
|
||||||
typingStatus={typingStatus}
|
typingStatus={typingStatus}
|
||||||
|
withMonoforumStatus={chat?.isMonoforum}
|
||||||
status={connectionStatusText || savedMessagesStatus}
|
status={connectionStatusText || savedMessagesStatus}
|
||||||
withDots={Boolean(connectionStatusText)}
|
withDots={Boolean(connectionStatusText)}
|
||||||
withMediaViewer={threadId === MAIN_THREAD_ID}
|
withMediaViewer={threadId === MAIN_THREAD_ID}
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import { memo } from '../../lib/teact/teact';
|
import { memo } from '../../lib/teact/teact';
|
||||||
import { getActions, withGlobal } from '../../global';
|
import { getActions, withGlobal } from '../../global';
|
||||||
|
|
||||||
import { getUserFirstOrLastName } from '../../global/helpers';
|
import type { ApiPeer } from '../../api/types';
|
||||||
import { selectTheme, selectThemeValues, selectUser } from '../../global/selectors';
|
|
||||||
|
import { getPeerTitle, isApiPeerUser } from '../../global/helpers/peers';
|
||||||
|
import { selectPeer, selectTheme, selectThemeValues } from '../../global/selectors';
|
||||||
import { formatStarsAsIcon } from '../../util/localization/format';
|
import { formatStarsAsIcon } from '../../util/localization/format';
|
||||||
import { LOCAL_TGS_URLS } from '../common/helpers/animatedAssets';
|
import { LOCAL_TGS_URLS } from '../common/helpers/animatedAssets';
|
||||||
import renderText from '../common/helpers/renderText';
|
import renderText from '../common/helpers/renderText';
|
||||||
@ -19,17 +21,18 @@ import Button from '../ui/Button';
|
|||||||
import styles from './RequirementToContactMessage.module.scss';
|
import styles from './RequirementToContactMessage.module.scss';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
|
peerId: string;
|
||||||
userId: string;
|
|
||||||
paidMessagesStars?: number;
|
paidMessagesStars?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps = {
|
||||||
patternColor?: string;
|
patternColor?: string;
|
||||||
userName?: string;
|
peer?: ApiPeer;
|
||||||
};
|
};
|
||||||
|
|
||||||
function RequirementToContactMessage({ patternColor, userName, paidMessagesStars }: OwnProps & StateProps) {
|
function RequirementToContactMessage({
|
||||||
|
patternColor, peer, paidMessagesStars,
|
||||||
|
}: OwnProps & StateProps) {
|
||||||
const oldLang = useOldLang();
|
const oldLang = useOldLang();
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const { openPremiumModal, openStarsBalanceModal } = getActions();
|
const { openPremiumModal, openStarsBalanceModal } = getActions();
|
||||||
@ -40,6 +43,8 @@ function RequirementToContactMessage({ patternColor, userName, paidMessagesStars
|
|||||||
openStarsBalanceModal({});
|
openStarsBalanceModal({});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!peer) return undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.root}>
|
<div className={styles.root}>
|
||||||
<div className={styles.inner}>
|
<div className={styles.inner}>
|
||||||
@ -55,8 +60,8 @@ function RequirementToContactMessage({ patternColor, userName, paidMessagesStars
|
|||||||
<span className={styles.description}>
|
<span className={styles.description}>
|
||||||
{
|
{
|
||||||
paidMessagesStars
|
paidMessagesStars
|
||||||
? lang('FirstMessageInPaidMessagesChat', {
|
? lang(isApiPeerUser(peer) ? 'MessagesPlaceholderPaidUser' : 'MessagesPlaceholderPaidChannel', {
|
||||||
user: userName,
|
peer: getPeerTitle(lang, peer),
|
||||||
amount: formatStarsAsIcon(lang,
|
amount: formatStarsAsIcon(lang,
|
||||||
paidMessagesStars,
|
paidMessagesStars,
|
||||||
{
|
{
|
||||||
@ -68,7 +73,7 @@ function RequirementToContactMessage({ patternColor, userName, paidMessagesStars
|
|||||||
withNodes: true,
|
withNodes: true,
|
||||||
withMarkdown: true,
|
withMarkdown: true,
|
||||||
})
|
})
|
||||||
: renderText(oldLang('MessageLockedPremium', userName), ['simple_markdown'])
|
: renderText(oldLang('MessageLockedPremium', getPeerTitle(lang, peer)), ['simple_markdown'])
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
<Button
|
<Button
|
||||||
@ -95,14 +100,14 @@ function RequirementToContactMessage({ patternColor, userName, paidMessagesStars
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default memo(
|
export default memo(
|
||||||
withGlobal<OwnProps>((global, { userId }): StateProps => {
|
withGlobal<OwnProps>((global, { peerId: userId }): StateProps => {
|
||||||
const theme = selectTheme(global);
|
const theme = selectTheme(global);
|
||||||
const { patternColor } = selectThemeValues(global, theme) || {};
|
const { patternColor } = selectThemeValues(global, theme) || {};
|
||||||
const user = selectUser(global, userId);
|
const peer = selectPeer(global, userId);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
patternColor,
|
patternColor,
|
||||||
userName: getUserFirstOrLastName(user),
|
peer,
|
||||||
};
|
};
|
||||||
})(RequirementToContactMessage),
|
})(RequirementToContactMessage),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import type { ChangeEvent } from 'react';
|
import type { ChangeEvent } from 'react';
|
||||||
import type { ElementRef, FC } from '../../../lib/teact/teact';
|
import type { ElementRef } from '../../../lib/teact/teact';
|
||||||
import type React from '../../../lib/teact/teact';
|
|
||||||
import {
|
import {
|
||||||
memo, useEffect, useRef, useState,
|
memo, useEffect, useRef, useState,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
@ -28,19 +27,25 @@ export type OwnProps = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
shouldBeAnonymous?: boolean;
|
shouldBeAnonymous?: boolean;
|
||||||
isQuiz?: boolean;
|
isQuiz?: boolean;
|
||||||
|
maxOptionsCount?: number;
|
||||||
onSend: (pollSummary: ApiNewPoll) => void;
|
onSend: (pollSummary: ApiNewPoll) => void;
|
||||||
onClear: () => void;
|
onClear: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const MAX_LIST_HEIGHT = 320;
|
const MAX_LIST_HEIGHT = 320;
|
||||||
const MAX_OPTIONS_COUNT = 10;
|
const FALLBACK_MAX_OPTIONS_COUNT = 12;
|
||||||
const MAX_OPTION_LENGTH = 100;
|
const MAX_OPTION_LENGTH = 100;
|
||||||
const MAX_QUESTION_LENGTH = 255;
|
const MAX_QUESTION_LENGTH = 255;
|
||||||
const MAX_SOLUTION_LENGTH = 200;
|
const MAX_SOLUTION_LENGTH = 200;
|
||||||
|
|
||||||
const PollModal: FC<OwnProps> = ({
|
const PollModal = ({
|
||||||
isOpen, isQuiz, shouldBeAnonymous, onSend, onClear,
|
isOpen,
|
||||||
}) => {
|
isQuiz,
|
||||||
|
shouldBeAnonymous,
|
||||||
|
maxOptionsCount = FALLBACK_MAX_OPTIONS_COUNT,
|
||||||
|
onSend,
|
||||||
|
onClear,
|
||||||
|
}: OwnProps) => {
|
||||||
const questionInputRef = useRef<HTMLInputElement>();
|
const questionInputRef = useRef<HTMLInputElement>();
|
||||||
const optionsListRef = useRef<HTMLDivElement>();
|
const optionsListRef = useRef<HTMLDivElement>();
|
||||||
|
|
||||||
@ -170,7 +175,7 @@ const PollModal: FC<OwnProps> = ({
|
|||||||
const updateOption = useLastCallback((index: number, text: string) => {
|
const updateOption = useLastCallback((index: number, text: string) => {
|
||||||
const newOptions = [...options];
|
const newOptions = [...options];
|
||||||
newOptions[index] = text;
|
newOptions[index] = text;
|
||||||
if (newOptions[newOptions.length - 1].trim().length && newOptions.length < MAX_OPTIONS_COUNT) {
|
if (newOptions[newOptions.length - 1].trim().length && newOptions.length < maxOptionsCount) {
|
||||||
addNewOption(newOptions);
|
addNewOption(newOptions);
|
||||||
} else {
|
} else {
|
||||||
setOptions(newOptions);
|
setOptions(newOptions);
|
||||||
@ -265,7 +270,7 @@ const PollModal: FC<OwnProps> = ({
|
|||||||
<div className="option-wrapper">
|
<div className="option-wrapper">
|
||||||
<InputText
|
<InputText
|
||||||
maxLength={MAX_OPTION_LENGTH}
|
maxLength={MAX_OPTION_LENGTH}
|
||||||
label={index !== options.length - 1 || options.length === MAX_OPTIONS_COUNT
|
label={index !== options.length - 1 || options.length === maxOptionsCount
|
||||||
? lang('OptionHint')
|
? lang('OptionHint')
|
||||||
: lang('CreatePoll.AddOption')}
|
: lang('CreatePoll.AddOption')}
|
||||||
error={getOptionsError(index)}
|
error={getOptionsError(index)}
|
||||||
|
|||||||
@ -717,13 +717,21 @@ const ActionMessageText = ({
|
|||||||
return action.message;
|
return action.message;
|
||||||
|
|
||||||
case 'paidMessagesPrice': {
|
case 'paidMessagesPrice': {
|
||||||
const { stars } = action;
|
const { stars, isAllowedInChannel } = action;
|
||||||
if (stars === 0) {
|
if (stars === 0) {
|
||||||
return lang('ActionPaidMessageGroupPriceFree');
|
if (isChannel) {
|
||||||
|
return lang(
|
||||||
|
isAllowedInChannel ? 'ActionMessageChannelFree' : 'ActionMessageChannelDisabled',
|
||||||
|
{ peer: chatLink },
|
||||||
|
{ withNodes: true },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return translateWithYou(lang, 'ActionPaidMessagePriceFree', isOutgoing, { peer: senderLink });
|
||||||
}
|
}
|
||||||
return lang('ActionPaidMessageGroupPrice', {
|
return translateWithYou(lang, 'ActionPaidMessagePrice', isOutgoing, {
|
||||||
stars: formatStarsAsText(lang, stars),
|
peer: senderLink,
|
||||||
}, { withNodes: true, withMarkdown: true });
|
amount: formatStarsAsText(lang, stars),
|
||||||
|
}, { withMarkdown: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'paidMessagesRefunded': {
|
case 'paidMessagesRefunded': {
|
||||||
|
|||||||
@ -65,6 +65,7 @@ import {
|
|||||||
selectPollFromMessage,
|
selectPollFromMessage,
|
||||||
selectRequestedChatTranslationLanguage,
|
selectRequestedChatTranslationLanguage,
|
||||||
selectRequestedMessageTranslationLanguage,
|
selectRequestedMessageTranslationLanguage,
|
||||||
|
selectSavedDialogIdFromMessage,
|
||||||
selectStickerSet,
|
selectStickerSet,
|
||||||
selectThreadInfo,
|
selectThreadInfo,
|
||||||
selectTopic,
|
selectTopic,
|
||||||
@ -156,6 +157,7 @@ type StateProps = {
|
|||||||
isWithPaidReaction?: boolean;
|
isWithPaidReaction?: boolean;
|
||||||
userFullName?: string;
|
userFullName?: string;
|
||||||
canGift?: boolean;
|
canGift?: boolean;
|
||||||
|
savedDialogId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const selection = window.getSelection();
|
const selection = window.getSelection();
|
||||||
@ -223,6 +225,7 @@ const ContextMenuContainer: FC<OwnProps & StateProps> = ({
|
|||||||
userFullName,
|
userFullName,
|
||||||
canGift,
|
canGift,
|
||||||
className,
|
className,
|
||||||
|
savedDialogId,
|
||||||
onClose,
|
onClose,
|
||||||
onCloseAnimationEnd,
|
onCloseAnimationEnd,
|
||||||
}) => {
|
}) => {
|
||||||
@ -416,6 +419,7 @@ const ContextMenuContainer: FC<OwnProps & StateProps> = ({
|
|||||||
replyToMsgId: message.id,
|
replyToMsgId: message.id,
|
||||||
quoteText,
|
quoteText,
|
||||||
quoteOffset: selectionQuoteOffset,
|
quoteOffset: selectionQuoteOffset,
|
||||||
|
monoforumPeerId: savedDialogId,
|
||||||
replyToPeerId: undefined,
|
replyToPeerId: undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -813,6 +817,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const hasTtl = hasMessageTtl(message);
|
const hasTtl = hasMessageTtl(message);
|
||||||
const canShowSeenBy = Boolean(!isLocal
|
const canShowSeenBy = Boolean(!isLocal
|
||||||
&& chat
|
&& chat
|
||||||
|
&& !chat.isMonoforum
|
||||||
&& !isMessageUnread
|
&& !isMessageUnread
|
||||||
&& seenByMaxChatMembers
|
&& seenByMaxChatMembers
|
||||||
&& seenByExpiresAt
|
&& seenByExpiresAt
|
||||||
@ -849,6 +854,8 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
|
|
||||||
const canGift = selectCanGift(global, message.chatId);
|
const canGift = selectCanGift(global, message.chatId);
|
||||||
|
|
||||||
|
const savedDialogId = selectSavedDialogIdFromMessage(global, message);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
threadId,
|
threadId,
|
||||||
chat,
|
chat,
|
||||||
@ -904,6 +911,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
story,
|
story,
|
||||||
userFullName,
|
userFullName,
|
||||||
canGift,
|
canGift,
|
||||||
|
savedDialogId,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(ContextMenuContainer));
|
)(ContextMenuContainer));
|
||||||
|
|||||||
@ -38,11 +38,11 @@ export function translateWithYou<K extends LangKey>(
|
|||||||
options?: {
|
options?: {
|
||||||
pluralValue?: number;
|
pluralValue?: number;
|
||||||
asText?: boolean;
|
asText?: boolean;
|
||||||
isMarkdown?: boolean;
|
withMarkdown?: boolean;
|
||||||
renderTextFilters?: string[];
|
renderTextFilters?: string[];
|
||||||
},
|
},
|
||||||
): TeactNode {
|
): TeactNode {
|
||||||
const { pluralValue, asText, isMarkdown, renderTextFilters } = options || {};
|
const { pluralValue, asText, withMarkdown, renderTextFilters } = options || {};
|
||||||
const translationKey = isYou ? (`${key}You` as LangKey) : key;
|
const translationKey = isYou ? (`${key}You` as LangKey) : key;
|
||||||
|
|
||||||
return lang(
|
return lang(
|
||||||
@ -50,7 +50,7 @@ export function translateWithYou<K extends LangKey>(
|
|||||||
translationKey,
|
translationKey,
|
||||||
variables,
|
variables,
|
||||||
{
|
{
|
||||||
withNodes: !asText, isMarkdown, pluralValue, renderTextFilters,
|
withNodes: !asText, withMarkdown, pluralValue, renderTextFilters,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import {
|
|||||||
selectForwardedSender,
|
selectForwardedSender,
|
||||||
selectIsChatWithSelf,
|
selectIsChatWithSelf,
|
||||||
selectIsCurrentUserPremium,
|
selectIsCurrentUserPremium,
|
||||||
|
selectMonoforumChannel,
|
||||||
selectSender,
|
selectSender,
|
||||||
selectTabState,
|
selectTabState,
|
||||||
} from '../../../global/selectors';
|
} from '../../../global/selectors';
|
||||||
@ -67,6 +68,7 @@ export type OwnProps = {
|
|||||||
type StateProps = {
|
type StateProps = {
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
chat?: ApiChat;
|
chat?: ApiChat;
|
||||||
|
monoforumChat?: ApiChat;
|
||||||
threadId?: ThreadId;
|
threadId?: ThreadId;
|
||||||
requestedQuery?: string;
|
requestedQuery?: string;
|
||||||
savedTags?: Record<ApiReactionKey, ApiSavedReactionTag>;
|
savedTags?: Record<ApiReactionKey, ApiSavedReactionTag>;
|
||||||
@ -97,6 +99,7 @@ const runDebouncedForSearch = debounce((cb) => cb(), 200, false);
|
|||||||
const MiddleSearch: FC<StateProps> = ({
|
const MiddleSearch: FC<StateProps> = ({
|
||||||
isActive,
|
isActive,
|
||||||
chat,
|
chat,
|
||||||
|
monoforumChat,
|
||||||
threadId,
|
threadId,
|
||||||
requestedQuery,
|
requestedQuery,
|
||||||
savedTags,
|
savedTags,
|
||||||
@ -645,7 +648,7 @@ const MiddleSearch: FC<StateProps> = ({
|
|||||||
{!isMobile && (
|
{!isMobile && (
|
||||||
<Avatar
|
<Avatar
|
||||||
className={styles.avatar}
|
className={styles.avatar}
|
||||||
peer={chat}
|
peer={monoforumChat || chat}
|
||||||
size="medium"
|
size="medium"
|
||||||
isSavedMessages={isSavedMessages}
|
isSavedMessages={isSavedMessages}
|
||||||
/>
|
/>
|
||||||
@ -793,8 +796,11 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
|
|
||||||
const savedTags = isSavedMessages && !isSavedDialog ? global.savedReactionTags?.byKey : undefined;
|
const savedTags = isSavedMessages && !isSavedDialog ? global.savedReactionTags?.byKey : undefined;
|
||||||
|
|
||||||
|
const monoforumChat = selectMonoforumChannel(global, chatId);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
chat,
|
chat,
|
||||||
|
monoforumChat,
|
||||||
requestedQuery,
|
requestedQuery,
|
||||||
totalCount,
|
totalCount,
|
||||||
threadId,
|
threadId,
|
||||||
|
|||||||
@ -77,7 +77,8 @@ const GifSearch: FC<OwnProps & StateProps> = ({
|
|||||||
observe: observeIntersection,
|
observe: observeIntersection,
|
||||||
} = useIntersectionObserver({ rootRef: containerRef, debounceMs: INTERSECTION_DEBOUNCE });
|
} = useIntersectionObserver({ rootRef: containerRef, debounceMs: INTERSECTION_DEBOUNCE });
|
||||||
|
|
||||||
const canSendGifs = canPostInChat && getAllowedAttachmentOptions(chat, chatFullInfo, isChatWithBot).canSendGifs;
|
const canSendGifs = canPostInChat
|
||||||
|
&& getAllowedAttachmentOptions(chat, chatFullInfo, isChatWithBot, isSavedMessages).canSendGifs;
|
||||||
|
|
||||||
const handleGifClick = useCallback((gif: ApiVideo, isSilent?: boolean, shouldSchedule?: boolean) => {
|
const handleGifClick = useCallback((gif: ApiVideo, isSilent?: boolean, shouldSchedule?: boolean) => {
|
||||||
if (canSendGifs) {
|
if (canSendGifs) {
|
||||||
|
|||||||
@ -49,6 +49,7 @@ import {
|
|||||||
selectCurrentSharedMediaSearch,
|
selectCurrentSharedMediaSearch,
|
||||||
selectIsCurrentUserPremium,
|
selectIsCurrentUserPremium,
|
||||||
selectIsRightColumnShown,
|
selectIsRightColumnShown,
|
||||||
|
selectMonoforumChannel,
|
||||||
selectPeerStories,
|
selectPeerStories,
|
||||||
selectSimilarBotsIds,
|
selectSimilarBotsIds,
|
||||||
selectSimilarChannelIds,
|
selectSimilarChannelIds,
|
||||||
@ -114,11 +115,12 @@ type OwnProps = {
|
|||||||
threadId?: ThreadId;
|
threadId?: ThreadId;
|
||||||
profileState: ProfileState;
|
profileState: ProfileState;
|
||||||
isMobile?: boolean;
|
isMobile?: boolean;
|
||||||
onProfileStateChange: (state: ProfileState) => void;
|
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
|
onProfileStateChange: (state: ProfileState) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps = {
|
||||||
|
monoforumChannel?: ApiChat;
|
||||||
theme: ThemeKey;
|
theme: ThemeKey;
|
||||||
isChannel?: boolean;
|
isChannel?: boolean;
|
||||||
isBot?: boolean;
|
isBot?: boolean;
|
||||||
@ -183,6 +185,7 @@ const Profile: FC<OwnProps & StateProps> = ({
|
|||||||
threadId,
|
threadId,
|
||||||
profileState,
|
profileState,
|
||||||
theme,
|
theme,
|
||||||
|
monoforumChannel,
|
||||||
isChannel,
|
isChannel,
|
||||||
isBot,
|
isBot,
|
||||||
currentUserId,
|
currentUserId,
|
||||||
@ -376,6 +379,9 @@ const Profile: FC<OwnProps & StateProps> = ({
|
|||||||
const handleLoadGifts = useCallback(() => {
|
const handleLoadGifts = useCallback(() => {
|
||||||
loadPeerSavedGifts({ peerId: chatId });
|
loadPeerSavedGifts({ peerId: chatId });
|
||||||
}, [chatId]);
|
}, [chatId]);
|
||||||
|
const handleLoadMoreMembers = useCallback(() => {
|
||||||
|
loadMoreMembers({ chatId });
|
||||||
|
}, [chatId, loadMoreMembers]);
|
||||||
|
|
||||||
useEffectWithPrevDeps(([prevGifts]) => {
|
useEffectWithPrevDeps(([prevGifts]) => {
|
||||||
if (!gifts || !prevGifts) {
|
if (!gifts || !prevGifts) {
|
||||||
@ -397,7 +403,7 @@ const Profile: FC<OwnProps & StateProps> = ({
|
|||||||
}, [gifts, startViewTransition]);
|
}, [gifts, startViewTransition]);
|
||||||
|
|
||||||
const [resultType, viewportIds, getMore, noProfileInfo] = useProfileViewportIds({
|
const [resultType, viewportIds, getMore, noProfileInfo] = useProfileViewportIds({
|
||||||
loadMoreMembers,
|
loadMoreMembers: handleLoadMoreMembers,
|
||||||
searchMessages: searchSharedMediaMessages,
|
searchMessages: searchSharedMediaMessages,
|
||||||
loadStories: handleLoadPeerStories,
|
loadStories: handleLoadPeerStories,
|
||||||
loadStoriesArchive: handleLoadStoriesArchive,
|
loadStoriesArchive: handleLoadStoriesArchive,
|
||||||
@ -872,7 +878,12 @@ const Profile: FC<OwnProps & StateProps> = ({
|
|||||||
onScroll={handleScroll}
|
onScroll={handleScroll}
|
||||||
>
|
>
|
||||||
{!noProfileInfo && !isSavedMessages && (
|
{!noProfileInfo && !isSavedMessages && (
|
||||||
renderProfileInfo(profileId, isRightColumnShown && canRenderContent, isSavedDialog)
|
renderProfileInfo(
|
||||||
|
monoforumChannel?.id || profileId,
|
||||||
|
isRightColumnShown && canRenderContent,
|
||||||
|
isSavedDialog,
|
||||||
|
Boolean(monoforumChannel),
|
||||||
|
)
|
||||||
)}
|
)}
|
||||||
{!isRestricted && (
|
{!isRestricted && (
|
||||||
<div
|
<div
|
||||||
@ -915,10 +926,10 @@ const Profile: FC<OwnProps & StateProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function renderProfileInfo(profileId: string, isReady: boolean, isSavedDialog?: boolean) {
|
function renderProfileInfo(profileId: string, isReady: boolean, isSavedDialog?: boolean, isForMonoforum?: boolean) {
|
||||||
return (
|
return (
|
||||||
<div className="profile-info">
|
<div className="profile-info">
|
||||||
<ProfileInfo peerId={profileId} canPlayVideo={isReady} />
|
<ProfileInfo peerId={profileId} canPlayVideo={isReady} isForMonoforum={isForMonoforum} />
|
||||||
<ChatExtra chatOrUserId={profileId} isSavedDialog={isSavedDialog} />
|
<ChatExtra chatOrUserId={profileId} isSavedDialog={isSavedDialog} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -949,7 +960,8 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const isGroup = chat && isChatGroup(chat);
|
const isGroup = chat && isChatGroup(chat);
|
||||||
const isChannel = chat && isChatChannel(chat);
|
const isChannel = chat && isChatChannel(chat);
|
||||||
const isBot = user && isUserBot(user);
|
const isBot = user && isUserBot(user);
|
||||||
const hasMembersTab = !isTopicInfo && !isSavedDialog && (isGroup || (isChannel && isChatAdmin(chat)));
|
const hasMembersTab = !isTopicInfo && !isSavedDialog
|
||||||
|
&& (isGroup || (isChannel && isChatAdmin(chat))) && !chat?.isMonoforum;
|
||||||
const members = chatFullInfo?.members;
|
const members = chatFullInfo?.members;
|
||||||
const adminMembersById = chatFullInfo?.adminMembersById;
|
const adminMembersById = chatFullInfo?.adminMembersById;
|
||||||
const areMembersHidden = hasMembersTab && chat
|
const areMembersHidden = hasMembersTab && chat
|
||||||
@ -984,6 +996,8 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const hasGiftsTab = Boolean(peerFullInfo?.starGiftCount) && !isSavedDialog;
|
const hasGiftsTab = Boolean(peerFullInfo?.starGiftCount) && !isSavedDialog;
|
||||||
const peerGifts = selectTabState(global).savedGifts.giftsByPeerId[chatId];
|
const peerGifts = selectTabState(global).savedGifts.giftsByPeerId[chatId];
|
||||||
|
|
||||||
|
const monoforumChannel = selectMonoforumChannel(global, chatId);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
theme: selectTheme(global),
|
theme: selectTheme(global),
|
||||||
isChannel,
|
isChannel,
|
||||||
@ -1025,6 +1039,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
limitSimilarPeers: selectPremiumLimit(global, 'recommendedChannels'),
|
limitSimilarPeers: selectPremiumLimit(global, 'recommendedChannels'),
|
||||||
...(hasMembersTab && members && { members, adminMembersById }),
|
...(hasMembersTab && members && { members, adminMembersById }),
|
||||||
...(hasCommonChatsTab && user && { commonChatIds: commonChats?.ids }),
|
...(hasCommonChatsTab && user && { commonChatIds: commonChats?.ids }),
|
||||||
|
monoforumChannel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(Profile));
|
)(Profile));
|
||||||
|
|||||||
@ -423,6 +423,7 @@ const RightColumn: FC<OwnProps & StateProps> = ({
|
|||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(withGlobal<OwnProps>(
|
||||||
(global, { isMobile }): StateProps => {
|
(global, { isMobile }): StateProps => {
|
||||||
const { chatId, threadId } = selectCurrentMessageList(global) || {};
|
const { chatId, threadId } = selectCurrentMessageList(global) || {};
|
||||||
|
|
||||||
const areActiveChatsLoaded = selectAreActiveChatsLoaded(global);
|
const areActiveChatsLoaded = selectAreActiveChatsLoaded(global);
|
||||||
const {
|
const {
|
||||||
management, shouldSkipHistoryAnimations, nextProfileTab, shouldCloseRightColumn,
|
management, shouldSkipHistoryAnimations, nextProfileTab, shouldCloseRightColumn,
|
||||||
|
|||||||
@ -173,12 +173,12 @@ const RightHeader: FC<OwnProps & StateProps> = ({
|
|||||||
isInsideTopic,
|
isInsideTopic,
|
||||||
canEditTopic,
|
canEditTopic,
|
||||||
isSavedMessages,
|
isSavedMessages,
|
||||||
onClose,
|
|
||||||
onScreenSelect,
|
|
||||||
canEditBot,
|
canEditBot,
|
||||||
giftProfileFilter,
|
giftProfileFilter,
|
||||||
canUseGiftFilter,
|
canUseGiftFilter,
|
||||||
canUseGiftAdminFilter,
|
canUseGiftAdminFilter,
|
||||||
|
onClose,
|
||||||
|
onScreenSelect,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
setStickerSearchQuery,
|
setStickerSearchQuery,
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import type { FC } from '../../../lib/teact/teact';
|
import type { FC } from '../../../lib/teact/teact';
|
||||||
import {
|
import {
|
||||||
memo, useCallback,
|
memo, useMemo, useState,
|
||||||
useMemo, useState,
|
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
import { getActions, withGlobal } from '../../../global';
|
import { getActions, withGlobal } from '../../../global';
|
||||||
|
|
||||||
@ -10,6 +9,7 @@ import type { ApiChat, ApiChatMember } from '../../../api/types';
|
|||||||
import { filterPeersByQuery } from '../../../global/helpers/peers';
|
import { filterPeersByQuery } from '../../../global/helpers/peers';
|
||||||
import { selectChatFullInfo } from '../../../global/selectors';
|
import { selectChatFullInfo } from '../../../global/selectors';
|
||||||
|
|
||||||
|
import useLastCallback from '../../../hooks/useLastCallback';
|
||||||
import useOldLang from '../../../hooks/useOldLang';
|
import useOldLang from '../../../hooks/useOldLang';
|
||||||
|
|
||||||
import ChatOrUserPicker from '../../common/pickers/ChatOrUserPicker';
|
import ChatOrUserPicker from '../../common/pickers/ChatOrUserPicker';
|
||||||
@ -52,10 +52,14 @@ const RemoveGroupUserModal: FC<OwnProps & StateProps> = ({
|
|||||||
return filterPeersByQuery({ ids: availableMemberIds, query: search, type: 'user' });
|
return filterPeersByQuery({ ids: availableMemberIds, query: search, type: 'user' });
|
||||||
}, [chatMembers, currentUserId, search]);
|
}, [chatMembers, currentUserId, search]);
|
||||||
|
|
||||||
const handleRemoveUser = useCallback((userId: string) => {
|
const handleLoadMore = useLastCallback(() => {
|
||||||
|
loadMoreMembers({ chatId: chat.id });
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleRemoveUser = useLastCallback((userId: string) => {
|
||||||
deleteChatMember({ chatId: chat.id, userId });
|
deleteChatMember({ chatId: chat.id, userId });
|
||||||
onClose();
|
onClose();
|
||||||
}, [chat.id, deleteChatMember, onClose]);
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChatOrUserPicker
|
<ChatOrUserPicker
|
||||||
@ -64,7 +68,7 @@ const RemoveGroupUserModal: FC<OwnProps & StateProps> = ({
|
|||||||
searchPlaceholder={lang('ChannelBlockUser')}
|
searchPlaceholder={lang('ChannelBlockUser')}
|
||||||
search={search}
|
search={search}
|
||||||
onSearchChange={setSearch}
|
onSearchChange={setSearch}
|
||||||
loadMore={loadMoreMembers}
|
loadMore={handleLoadMore}
|
||||||
onSelectChatOrUser={handleRemoveUser}
|
onSelectChatOrUser={handleRemoveUser}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -343,7 +343,7 @@ export const REPLIES_USER_ID = '1271266957'; // TODO For Test connection ID must
|
|||||||
export const VERIFICATION_CODES_USER_ID = '489000';
|
export const VERIFICATION_CODES_USER_ID = '489000';
|
||||||
export const ANONYMOUS_USER_ID = '2666000';
|
export const ANONYMOUS_USER_ID = '2666000';
|
||||||
export const RESTRICTED_EMOJI_SET_ID = '7173162320003080';
|
export const RESTRICTED_EMOJI_SET_ID = '7173162320003080';
|
||||||
export const CHANNEL_ID_LENGTH = 14; // 14 symbols, based on TDLib's `ZERO_CHANNEL_ID = -1000000000000`
|
export const CHANNEL_ID_BASE = 10 ** 12;
|
||||||
export const DEFAULT_GIF_SEARCH_BOT_USERNAME = 'gif';
|
export const DEFAULT_GIF_SEARCH_BOT_USERNAME = 'gif';
|
||||||
export const ALL_FOLDER_ID = 0;
|
export const ALL_FOLDER_ID = 0;
|
||||||
export const ARCHIVED_FOLDER_ID = 1;
|
export const ARCHIVED_FOLDER_ID = 1;
|
||||||
|
|||||||
@ -52,6 +52,7 @@ import {
|
|||||||
isChatArchived,
|
isChatArchived,
|
||||||
isChatBasicGroup,
|
isChatBasicGroup,
|
||||||
isChatChannel,
|
isChatChannel,
|
||||||
|
isChatMonoforum,
|
||||||
isChatSuperGroup,
|
isChatSuperGroup,
|
||||||
isUserBot,
|
isUserBot,
|
||||||
} from '../../helpers';
|
} from '../../helpers';
|
||||||
@ -2130,11 +2131,11 @@ addActionHandler('resetOpenChatWithDraft', (global, actions, payload): ActionRet
|
|||||||
});
|
});
|
||||||
|
|
||||||
addActionHandler('loadMoreMembers', async (global, actions, payload): Promise<void> => {
|
addActionHandler('loadMoreMembers', async (global, actions, payload): Promise<void> => {
|
||||||
|
const { chatId } = payload || {};
|
||||||
|
|
||||||
if (selectIsCurrentUserFrozen(global)) return;
|
if (selectIsCurrentUserFrozen(global)) return;
|
||||||
const { tabId = getCurrentTabId() } = payload || {};
|
const chat = selectChat(global, chatId);
|
||||||
const { chatId } = selectCurrentMessageList(global, tabId) || {};
|
if (!chat || isChatBasicGroup(chat) || isChatMonoforum(chat)) {
|
||||||
const chat = chatId ? selectChat(global, chatId) : undefined;
|
|
||||||
if (!chat || isChatBasicGroup(chat)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -581,12 +581,17 @@ addActionHandler('saveDraft', (global, actions, payload): ActionReturnType => {
|
|||||||
const {
|
const {
|
||||||
chatId, threadId, text,
|
chatId, threadId, text,
|
||||||
} = payload;
|
} = payload;
|
||||||
if (!text) {
|
const chat = selectChat(global, chatId);
|
||||||
|
if (!text || !chat) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentDraft = selectDraft(global, chatId, threadId);
|
const currentDraft = selectDraft(global, chatId, threadId);
|
||||||
|
|
||||||
|
if (chat.isMonoforum && !currentDraft?.replyInfo) {
|
||||||
|
return; // Monoforum doesn't support drafts outside threads
|
||||||
|
}
|
||||||
|
|
||||||
const newDraft: ApiDraft = {
|
const newDraft: ApiDraft = {
|
||||||
text,
|
text,
|
||||||
replyInfo: currentDraft?.replyInfo,
|
replyInfo: currentDraft?.replyInfo,
|
||||||
@ -654,8 +659,12 @@ addActionHandler('resetDraftReplyInfo', (global, actions, payload): ActionReturn
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { chatId, threadId } = currentMessageList;
|
const { chatId, threadId } = currentMessageList;
|
||||||
|
const chat = selectChat(global, chatId);
|
||||||
|
|
||||||
const currentDraft = selectDraft(global, chatId, threadId);
|
const currentDraft = selectDraft(global, chatId, threadId);
|
||||||
|
if (chat?.isMonoforum && !currentDraft?.replyInfo) {
|
||||||
|
return; // Monoforum doesn't support drafts outside threads
|
||||||
|
}
|
||||||
const newDraft: ApiDraft | undefined = !currentDraft?.text ? undefined : {
|
const newDraft: ApiDraft | undefined = !currentDraft?.text ? undefined : {
|
||||||
...currentDraft,
|
...currentDraft,
|
||||||
replyInfo: undefined,
|
replyInfo: undefined,
|
||||||
@ -671,7 +680,11 @@ addActionHandler('saveEffectInDraft', (global, actions, payload): ActionReturnTy
|
|||||||
chatId, threadId, effectId,
|
chatId, threadId, effectId,
|
||||||
} = payload;
|
} = payload;
|
||||||
|
|
||||||
|
const chat = selectChat(global, chatId);
|
||||||
const currentDraft = selectDraft(global, chatId, threadId);
|
const currentDraft = selectDraft(global, chatId, threadId);
|
||||||
|
if (chat?.isMonoforum && !currentDraft?.replyInfo) {
|
||||||
|
return; // Monoforum doesn't support drafts outside threads
|
||||||
|
}
|
||||||
|
|
||||||
const newDraft = {
|
const newDraft = {
|
||||||
...currentDraft,
|
...currentDraft,
|
||||||
@ -986,7 +999,7 @@ addActionHandler('sendMessageAction', async (global, actions, payload): Promise<
|
|||||||
if (selectIsChatWithSelf(global, chatId)) return;
|
if (selectIsChatWithSelf(global, chatId)) return;
|
||||||
|
|
||||||
const chat = selectChat(global, chatId)!;
|
const chat = selectChat(global, chatId)!;
|
||||||
if (!chat) return;
|
if (!chat || chat.isMonoforum) return;
|
||||||
const user = selectUser(global, chatId);
|
const user = selectUser(global, chatId);
|
||||||
if (user && (isUserBot(user) || isDeletedUser(user))) return;
|
if (user && (isUserBot(user) || isDeletedUser(user))) return;
|
||||||
|
|
||||||
@ -2140,6 +2153,7 @@ addActionHandler('openChatOrTopicWithReplyInDraft', (global, actions, payload):
|
|||||||
replyToMsgId: replyingInfo.messageId,
|
replyToMsgId: replyingInfo.messageId,
|
||||||
replyToTopId: replyingInfo.toThreadId,
|
replyToTopId: replyingInfo.toThreadId,
|
||||||
replyToPeerId: currentChatId,
|
replyToPeerId: currentChatId,
|
||||||
|
monoforumPeerId: replyingInfo.toThreadId,
|
||||||
quoteText: replyingInfo.quoteText,
|
quoteText: replyingInfo.quoteText,
|
||||||
quoteOffset: replyingInfo.quoteOffset,
|
quoteOffset: replyingInfo.quoteOffset,
|
||||||
} as ApiInputMessageReplyInfo;
|
} as ApiInputMessageReplyInfo;
|
||||||
|
|||||||
@ -30,6 +30,8 @@ import {
|
|||||||
selectChatMessage,
|
selectChatMessage,
|
||||||
selectCurrentChat,
|
selectCurrentChat,
|
||||||
selectCurrentMessageList,
|
selectCurrentMessageList,
|
||||||
|
selectIsChatWithBot,
|
||||||
|
selectIsChatWithSelf,
|
||||||
selectIsCurrentUserPremium,
|
selectIsCurrentUserPremium,
|
||||||
selectIsTrustedBot,
|
selectIsTrustedBot,
|
||||||
selectPeerPaidMessagesStars,
|
selectPeerPaidMessagesStars,
|
||||||
@ -344,11 +346,13 @@ addActionHandler('showAllowedMessageTypesNotification', (global, actions, payloa
|
|||||||
const chat = selectChat(global, chatId);
|
const chat = selectChat(global, chatId);
|
||||||
if (!chat) return;
|
if (!chat) return;
|
||||||
const chatFullInfo = selectChatFullInfo(global, chatId);
|
const chatFullInfo = selectChatFullInfo(global, chatId);
|
||||||
|
const isSavedMessages = chatId ? selectIsChatWithSelf(global, chatId) : undefined;
|
||||||
|
const isChatWithBot = chatId ? selectIsChatWithBot(global, chat) : undefined;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
canSendPlainText, canSendPhotos, canSendVideos, canSendDocuments, canSendAudios,
|
canSendPlainText, canSendPhotos, canSendVideos, canSendDocuments, canSendAudios,
|
||||||
canSendStickers, canSendRoundVideos, canSendVoices,
|
canSendStickers, canSendRoundVideos, canSendVoices,
|
||||||
} = getAllowedAttachmentOptions(chat, chatFullInfo);
|
} = getAllowedAttachmentOptions(chat, chatFullInfo, isChatWithBot, isSavedMessages);
|
||||||
const allowedContent = compact([
|
const allowedContent = compact([
|
||||||
canSendPlainText ? 'Chat.SendAllowedContentTypeText' : undefined,
|
canSendPlainText ? 'Chat.SendAllowedContentTypeText' : undefined,
|
||||||
canSendPhotos ? 'Chat.SendAllowedContentTypePhoto' : undefined,
|
canSendPhotos ? 'Chat.SendAllowedContentTypePhoto' : undefined,
|
||||||
|
|||||||
@ -47,6 +47,10 @@ export function isChatChannel(chat: ApiChat) {
|
|||||||
return chat.type === 'chatTypeChannel';
|
return chat.type === 'chatTypeChannel';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isChatMonoforum(chat: ApiChat) {
|
||||||
|
return chat.isMonoforum;
|
||||||
|
}
|
||||||
|
|
||||||
export function isCommonBoxChat(chat: ApiChat) {
|
export function isCommonBoxChat(chat: ApiChat) {
|
||||||
return chat.type === 'chatTypePrivate' || chat.type === 'chatTypeBasicGroup';
|
return chat.type === 'chatTypePrivate' || chat.type === 'chatTypeBasicGroup';
|
||||||
}
|
}
|
||||||
@ -152,7 +156,8 @@ export function getCanPostInChat(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (chat.isRestricted || chat.isForbidden || chat.migratedTo
|
if (chat.isRestricted || chat.isForbidden || chat.migratedTo
|
||||||
|| (!isMessageThread && chat.isNotJoined) || isSystemBot(chat.id) || isAnonymousForwardsChat(chat.id)) {
|
|| (chat.isNotJoined && !isChatMonoforum(chat) && !isMessageThread)
|
||||||
|
|| isSystemBot(chat.id) || isAnonymousForwardsChat(chat.id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,6 +195,7 @@ export function getAllowedAttachmentOptions(
|
|||||||
chat?: ApiChat,
|
chat?: ApiChat,
|
||||||
chatFullInfo?: ApiChatFullInfo,
|
chatFullInfo?: ApiChatFullInfo,
|
||||||
isChatWithBot = false,
|
isChatWithBot = false,
|
||||||
|
isSavedMessages = false,
|
||||||
isStoryReply = false,
|
isStoryReply = false,
|
||||||
paidMessagesStars?: number,
|
paidMessagesStars?: number,
|
||||||
isInScheduledList = false,
|
isInScheduledList = false,
|
||||||
@ -215,9 +221,9 @@ export function getAllowedAttachmentOptions(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
canAttachMedia: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendMedia', chatFullInfo),
|
canAttachMedia: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendMedia', chatFullInfo),
|
||||||
canAttachPolls: !isStoryReply
|
canAttachPolls: !isStoryReply && !chat.isMonoforum
|
||||||
&& (isAdmin || !isUserRightBanned(chat, 'sendPolls', chatFullInfo))
|
&& (isAdmin || !isUserRightBanned(chat, 'sendPolls', chatFullInfo))
|
||||||
&& (!isUserId(chat.id) || isChatWithBot),
|
&& (!isUserId(chat.id) || isChatWithBot || isSavedMessages),
|
||||||
canSendStickers: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendStickers', chatFullInfo),
|
canSendStickers: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendStickers', chatFullInfo),
|
||||||
canSendGifs: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendGifs', chatFullInfo),
|
canSendGifs: isAdmin || isStoryReply || !isUserRightBanned(chat, 'sendGifs', chatFullInfo),
|
||||||
canAttachEmbedLinks: !isStoryReply && (isAdmin || !isUserRightBanned(chat, 'embedLinks', chatFullInfo)),
|
canAttachEmbedLinks: !isStoryReply && (isAdmin || !isUserRightBanned(chat, 'embedLinks', chatFullInfo)),
|
||||||
|
|||||||
@ -349,3 +349,28 @@ export function selectChatLastMessage<T extends GlobalState>(
|
|||||||
const realChatId = listType === 'saved' ? global.currentUserId! : chatId;
|
const realChatId = listType === 'saved' ? global.currentUserId! : chatId;
|
||||||
return global.messages.byChatId[realChatId]?.byId[id];
|
return global.messages.byChatId[realChatId]?.byId[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function selectIsMonoforumAdmin<T extends GlobalState>(
|
||||||
|
global: T, chatId: string,
|
||||||
|
) {
|
||||||
|
const chat = selectChat(global, chatId);
|
||||||
|
if (!chat?.isMonoforum) return;
|
||||||
|
|
||||||
|
const channel = selectMonoforumChannel(global, chatId);
|
||||||
|
if (!channel) return;
|
||||||
|
|
||||||
|
return Boolean(chat.isCreator || chat.adminRights || channel.isCreator || channel.adminRights);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only selects monoforum channel for monoforum chats.
|
||||||
|
* Returns `undefined` for other chats, including channels that have linked monoforum.
|
||||||
|
*/
|
||||||
|
export function selectMonoforumChannel<T extends GlobalState>(
|
||||||
|
global: T, chatId: string,
|
||||||
|
) {
|
||||||
|
const chat = selectChat(global, chatId);
|
||||||
|
if (!chat) return;
|
||||||
|
|
||||||
|
return chat.isMonoforum ? selectChat(global, chat.linkedMonoforumId!) : undefined;
|
||||||
|
}
|
||||||
|
|||||||
@ -72,7 +72,7 @@ export function selectCanManage<T extends GlobalState>(
|
|||||||
chatId: string,
|
chatId: string,
|
||||||
) {
|
) {
|
||||||
const chat = selectChat(global, chatId);
|
const chat = selectChat(global, chatId);
|
||||||
if (!chat || chat.isRestricted) return false;
|
if (!chat || chat.isRestricted || chat.isMonoforum) return false;
|
||||||
|
|
||||||
const isPrivate = isUserId(chat.id);
|
const isPrivate = isUserId(chat.id);
|
||||||
const user = isPrivate ? selectUser(global, chatId) : undefined;
|
const user = isPrivate ? selectUser(global, chatId) : undefined;
|
||||||
|
|||||||
@ -72,6 +72,7 @@ import {
|
|||||||
selectChat,
|
selectChat,
|
||||||
selectChatFullInfo,
|
selectChatFullInfo,
|
||||||
selectChatLastMessageId,
|
selectChatLastMessageId,
|
||||||
|
selectIsChatWithBot,
|
||||||
selectIsChatWithSelf,
|
selectIsChatWithSelf,
|
||||||
selectRequestedChatTranslationLanguage,
|
selectRequestedChatTranslationLanguage,
|
||||||
} from './chats';
|
} from './chats';
|
||||||
@ -651,6 +652,7 @@ export function selectAllowedMessageActionsSlow<T extends GlobalState>(
|
|||||||
const { content } = message;
|
const { content } = message;
|
||||||
const isDocumentSticker = isMessageDocumentSticker(message);
|
const isDocumentSticker = isMessageDocumentSticker(message);
|
||||||
const isBoostMessage = message.content.action?.type === 'boostApply';
|
const isBoostMessage = message.content.action?.type === 'boostApply';
|
||||||
|
const isMonoforum = chat.isMonoforum;
|
||||||
|
|
||||||
const hasChatPinPermission = (chat.isCreator
|
const hasChatPinPermission = (chat.isCreator
|
||||||
|| (!isChannel && !isUserRightBanned(chat, 'pinMessages'))
|
|| (!isChannel && !isUserRightBanned(chat, 'pinMessages'))
|
||||||
@ -726,7 +728,7 @@ export function selectAllowedMessageActionsSlow<T extends GlobalState>(
|
|||||||
const canFaveSticker = !isAction && hasSticker && !hasFavoriteSticker;
|
const canFaveSticker = !isAction && hasSticker && !hasFavoriteSticker;
|
||||||
const canUnfaveSticker = !isAction && hasFavoriteSticker;
|
const canUnfaveSticker = !isAction && hasFavoriteSticker;
|
||||||
const canCopy = !isAction;
|
const canCopy = !isAction;
|
||||||
const canCopyLink = !isLocal && !isAction && (isChannel || isSuperGroup);
|
const canCopyLink = !isLocal && !isAction && (isChannel || isSuperGroup) && !isMonoforum;
|
||||||
const canSelect = !isLocal && !isAction;
|
const canSelect = !isLocal && !isAction;
|
||||||
|
|
||||||
const canDownload = Boolean(content.webPage?.document || content.webPage?.video || content.webPage?.photo
|
const canDownload = Boolean(content.webPage?.document || content.webPage?.video || content.webPage?.photo
|
||||||
@ -1462,7 +1464,10 @@ export function selectForwardsCanBeSentToChat<T extends GlobalState>(
|
|||||||
|
|
||||||
const chatFullInfo = selectChatFullInfo(global, toChatId);
|
const chatFullInfo = selectChatFullInfo(global, toChatId);
|
||||||
const chatMessages = selectChatMessages(global, fromChatId!);
|
const chatMessages = selectChatMessages(global, fromChatId!);
|
||||||
const options = getAllowedAttachmentOptions(chat, chatFullInfo);
|
|
||||||
|
const isSavedMessages = toChatId ? selectIsChatWithSelf(global, toChatId) : undefined;
|
||||||
|
const isChatWithBot = toChatId ? selectIsChatWithBot(global, chat) : undefined;
|
||||||
|
const options = getAllowedAttachmentOptions(chat, chatFullInfo, isChatWithBot, isSavedMessages);
|
||||||
return !messageIds!.some((messageId) => сheckMessageSendingDenied(chatMessages[messageId], options));
|
return !messageIds!.some((messageId) => сheckMessageSendingDenied(chatMessages[messageId], options));
|
||||||
}
|
}
|
||||||
function сheckMessageSendingDenied(message: ApiMessage, options: IAllowedAttachmentOptions) {
|
function сheckMessageSendingDenied(message: ApiMessage, options: IAllowedAttachmentOptions) {
|
||||||
|
|||||||
@ -354,7 +354,9 @@ export interface ActionPayloads {
|
|||||||
} & WithTabId;
|
} & WithTabId;
|
||||||
openThreadWithInfo: ActionPayloads['openThread'] & WithTabId;
|
openThreadWithInfo: ActionPayloads['openThread'] & WithTabId;
|
||||||
openLinkedChat: { id: string } & WithTabId;
|
openLinkedChat: { id: string } & WithTabId;
|
||||||
loadMoreMembers: WithTabId | undefined;
|
loadMoreMembers: {
|
||||||
|
chatId: string;
|
||||||
|
};
|
||||||
setActiveChatFolder: {
|
setActiveChatFolder: {
|
||||||
activeChatFolder: number;
|
activeChatFolder: number;
|
||||||
} & WithTabId;
|
} & WithTabId;
|
||||||
|
|||||||
@ -12,5 +12,5 @@ for (const tl of Object.values(Api)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LAYER = 203;
|
export const LAYER = 204;
|
||||||
export { tlobjects };
|
export { tlobjects };
|
||||||
|
|||||||
167
src/lib/gramjs/tl/api.d.ts
vendored
167
src/lib/gramjs/tl/api.d.ts
vendored
File diff suppressed because one or more lines are too long
@ -80,7 +80,7 @@ userStatusLastMonth#65899777 flags:# by_me:flags.0?true = UserStatus;
|
|||||||
chatEmpty#29562865 id:long = Chat;
|
chatEmpty#29562865 id:long = Chat;
|
||||||
chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
|
chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
|
||||||
chatForbidden#6592a1a7 id:long title:string = Chat;
|
chatForbidden#6592a1a7 id:long title:string = Chat;
|
||||||
channel#7482147e 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 signature_profiles:flags2.12?true autotranslation:flags2.15?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 subscription_until_date:flags2.11?int bot_verification_icon:flags2.13?long send_paid_messages_stars:flags2.14?long = Chat;
|
channel#fe685355 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 signature_profiles:flags2.12?true autotranslation:flags2.15?true broadcast_messages_allowed:flags2.16?true monoforum:flags2.17?true forum_tabs:flags2.19?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 subscription_until_date:flags2.11?int bot_verification_icon:flags2.13?long send_paid_messages_stars:flags2.14?long linked_monoforum_id:flags2.18?long = Chat;
|
||||||
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
|
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
|
||||||
chatFull#2633421b 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 reactions_limit:flags.20?int = ChatFull;
|
chatFull#2633421b 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 reactions_limit:flags.20?int = ChatFull;
|
||||||
channelFull#52d6806b 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 restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true paid_reactions_available:flags2.16?true stargifts_available:flags2.19?true paid_messages_available:flags2.20?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 reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet bot_verification:flags2.17?BotVerification stargifts_count:flags2.18?int = ChatFull;
|
channelFull#52d6806b 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 restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true paid_reactions_available:flags2.16?true stargifts_available:flags2.19?true paid_messages_available:flags2.20?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 reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet bot_verification:flags2.17?BotVerification stargifts_count:flags2.18?int = ChatFull;
|
||||||
@ -160,7 +160,7 @@ messageActionPrizeStars#b00c47a2 flags:# unclaimed:flags.0?true stars:long trans
|
|||||||
messageActionStarGift#4717e8a4 flags:# name_hidden:flags.0?true saved:flags.2?true converted:flags.3?true upgraded:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true gift:StarGift message:flags.1?TextWithEntities convert_stars:flags.4?long upgrade_msg_id:flags.5?int upgrade_stars:flags.8?long from_id:flags.11?Peer peer:flags.12?Peer saved_id:flags.12?long = MessageAction;
|
messageActionStarGift#4717e8a4 flags:# name_hidden:flags.0?true saved:flags.2?true converted:flags.3?true upgraded:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true gift:StarGift message:flags.1?TextWithEntities convert_stars:flags.4?long upgrade_msg_id:flags.5?int upgrade_stars:flags.8?long from_id:flags.11?Peer peer:flags.12?Peer saved_id:flags.12?long = MessageAction;
|
||||||
messageActionStarGiftUnique#2e3ae60e flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long from_id:flags.6?Peer peer:flags.7?Peer saved_id:flags.7?long resale_stars:flags.8?long can_transfer_at:flags.9?int can_resell_at:flags.10?int = MessageAction;
|
messageActionStarGiftUnique#2e3ae60e flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long from_id:flags.6?Peer peer:flags.7?Peer saved_id:flags.7?long resale_stars:flags.8?long can_transfer_at:flags.9?int can_resell_at:flags.10?int = MessageAction;
|
||||||
messageActionPaidMessagesRefunded#ac1f1fcd count:int stars:long = MessageAction;
|
messageActionPaidMessagesRefunded#ac1f1fcd count:int stars:long = MessageAction;
|
||||||
messageActionPaidMessagesPrice#bcd71419 stars:long = MessageAction;
|
messageActionPaidMessagesPrice#84b88578 flags:# broadcast_messages_allowed:flags.0?true stars:long = MessageAction;
|
||||||
messageActionConferenceCall#2ffe2f7a flags:# missed:flags.0?true active:flags.1?true video:flags.4?true call_id:long duration:flags.2?int other_participants:flags.3?Vector<Peer> = MessageAction;
|
messageActionConferenceCall#2ffe2f7a flags:# missed:flags.0?true active:flags.1?true video:flags.4?true call_id:long duration:flags.2?int other_participants:flags.3?Vector<Peer> = MessageAction;
|
||||||
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
||||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||||
@ -279,7 +279,7 @@ updateBotCallbackQuery#b9cfc48d flags:# query_id:long user_id:long peer:Peer msg
|
|||||||
updateEditMessage#e40370a3 message:Message pts:int pts_count:int = Update;
|
updateEditMessage#e40370a3 message:Message pts:int pts_count:int = Update;
|
||||||
updateInlineBotCallbackQuery#691e9052 flags:# query_id:long user_id:long msg_id:InputBotInlineMessageID chat_instance:long data:flags.0?bytes game_short_name:flags.1?string = Update;
|
updateInlineBotCallbackQuery#691e9052 flags:# query_id:long user_id:long msg_id:InputBotInlineMessageID chat_instance:long data:flags.0?bytes game_short_name:flags.1?string = Update;
|
||||||
updateReadChannelOutbox#b75f99a9 channel_id:long max_id:int = Update;
|
updateReadChannelOutbox#b75f99a9 channel_id:long max_id:int = Update;
|
||||||
updateDraftMessage#1b49ec6d flags:# peer:Peer top_msg_id:flags.0?int draft:DraftMessage = Update;
|
updateDraftMessage#edfc111e flags:# peer:Peer top_msg_id:flags.0?int saved_peer_id:flags.1?Peer draft:DraftMessage = Update;
|
||||||
updateReadFeaturedStickers#571d2742 = Update;
|
updateReadFeaturedStickers#571d2742 = Update;
|
||||||
updateRecentStickers#9a422c20 = Update;
|
updateRecentStickers#9a422c20 = Update;
|
||||||
updateConfig#a229dd06 = Update;
|
updateConfig#a229dd06 = Update;
|
||||||
@ -295,10 +295,10 @@ updatePhoneCall#ab0f6b1e phone_call:PhoneCall = Update;
|
|||||||
updateLangPackTooLong#46560264 lang_code:string = Update;
|
updateLangPackTooLong#46560264 lang_code:string = Update;
|
||||||
updateLangPack#56022f4d difference:LangPackDifference = Update;
|
updateLangPack#56022f4d difference:LangPackDifference = Update;
|
||||||
updateFavedStickers#e511996d = Update;
|
updateFavedStickers#e511996d = Update;
|
||||||
updateChannelReadMessagesContents#ea29055d flags:# channel_id:long top_msg_id:flags.0?int messages:Vector<int> = Update;
|
updateChannelReadMessagesContents#25f324f7 flags:# channel_id:long top_msg_id:flags.0?int saved_peer_id:flags.1?Peer messages:Vector<int> = Update;
|
||||||
updateContactsReset#7084a7be = Update;
|
updateContactsReset#7084a7be = Update;
|
||||||
updateChannelAvailableMessages#b23fc698 channel_id:long available_min_id:int = Update;
|
updateChannelAvailableMessages#b23fc698 channel_id:long available_min_id:int = Update;
|
||||||
updateDialogUnreadMark#e16459c3 flags:# unread:flags.0?true peer:DialogPeer = Update;
|
updateDialogUnreadMark#b658f23e flags:# unread:flags.0?true peer:DialogPeer saved_peer_id:flags.1?Peer = Update;
|
||||||
updateMessagePoll#aca1657b flags:# poll_id:long poll:flags.0?Poll results:PollResults = Update;
|
updateMessagePoll#aca1657b flags:# poll_id:long poll:flags.0?Poll results:PollResults = Update;
|
||||||
updateChatDefaultBannedRights#54c01850 peer:Peer default_banned_rights:ChatBannedRights version:int = Update;
|
updateChatDefaultBannedRights#54c01850 peer:Peer default_banned_rights:ChatBannedRights version:int = Update;
|
||||||
updateFolderPeers#19360dc0 folder_peers:Vector<FolderPeer> pts:int pts_count:int = Update;
|
updateFolderPeers#19360dc0 folder_peers:Vector<FolderPeer> pts:int pts_count:int = Update;
|
||||||
@ -332,7 +332,7 @@ updateGroupCallConnection#b783982 flags:# presentation:flags.0?true params:DataJ
|
|||||||
updateBotCommands#4d712f2e peer:Peer bot_id:long commands:Vector<BotCommand> = Update;
|
updateBotCommands#4d712f2e peer:Peer bot_id:long commands:Vector<BotCommand> = Update;
|
||||||
updatePendingJoinRequests#7063c3db peer:Peer requests_pending:int recent_requesters:Vector<long> = Update;
|
updatePendingJoinRequests#7063c3db peer:Peer requests_pending:int recent_requesters:Vector<long> = Update;
|
||||||
updateBotChatInviteRequester#11dfa986 peer:Peer date:int user_id:long about:string invite:ExportedChatInvite qts:int = Update;
|
updateBotChatInviteRequester#11dfa986 peer:Peer date:int user_id:long about:string invite:ExportedChatInvite qts:int = Update;
|
||||||
updateMessageReactions#5e1b3cb8 flags:# peer:Peer msg_id:int top_msg_id:flags.0?int reactions:MessageReactions = Update;
|
updateMessageReactions#1e297bfa flags:# peer:Peer msg_id:int top_msg_id:flags.0?int saved_peer_id:flags.1?Peer reactions:MessageReactions = Update;
|
||||||
updateAttachMenuBots#17b7a20b = Update;
|
updateAttachMenuBots#17b7a20b = Update;
|
||||||
updateWebViewResultSent#1592b79d query_id:long = Update;
|
updateWebViewResultSent#1592b79d query_id:long = Update;
|
||||||
updateBotMenuButton#14b85813 bot_id:long button:BotMenuButton = Update;
|
updateBotMenuButton#14b85813 bot_id:long button:BotMenuButton = Update;
|
||||||
@ -380,6 +380,8 @@ updateBotPurchasedPaidMedia#283bd312 user_id:long payload:string qts:int = Updat
|
|||||||
updatePaidReactionPrivacy#8b725fce private:PaidReactionPrivacy = Update;
|
updatePaidReactionPrivacy#8b725fce private:PaidReactionPrivacy = Update;
|
||||||
updateSentPhoneCode#504aa18f sent_code:auth.SentCode = Update;
|
updateSentPhoneCode#504aa18f sent_code:auth.SentCode = Update;
|
||||||
updateGroupCallChainBlocks#a477288f call:InputGroupCall sub_chain_id:int blocks:Vector<bytes> next_offset:int = Update;
|
updateGroupCallChainBlocks#a477288f call:InputGroupCall sub_chain_id:int blocks:Vector<bytes> next_offset:int = Update;
|
||||||
|
updateReadMonoForumInbox#77b0e372 channel_id:long saved_peer_id:Peer read_max_id:int = Update;
|
||||||
|
updateReadMonoForumOutbox#a4a79376 channel_id:long saved_peer_id:Peer read_max_id:int = Update;
|
||||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||||
updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference;
|
updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference;
|
||||||
updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference;
|
updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference;
|
||||||
@ -1234,8 +1236,9 @@ storyViewPublicForward#9083670b flags:# blocked:flags.0?true blocked_my_stories_
|
|||||||
storyViewPublicRepost#bd74cf49 flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true peer_id:Peer story:StoryItem = StoryView;
|
storyViewPublicRepost#bd74cf49 flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true peer_id:Peer story:StoryItem = StoryView;
|
||||||
stories.storyViewsList#59d78fc5 flags:# count:int views_count:int forwards_count:int reactions_count:int views:Vector<StoryView> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryViewsList;
|
stories.storyViewsList#59d78fc5 flags:# count:int views_count:int forwards_count:int reactions_count:int views:Vector<StoryView> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryViewsList;
|
||||||
stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews;
|
stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews;
|
||||||
inputReplyToMessage#22c0f6d5 flags:# reply_to_msg_id:int top_msg_id:flags.0?int reply_to_peer_id:flags.1?InputPeer quote_text:flags.2?string quote_entities:flags.3?Vector<MessageEntity> quote_offset:flags.4?int = InputReplyTo;
|
inputReplyToMessage#b07038b0 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 monoforum_peer_id:flags.5?InputPeer = InputReplyTo;
|
||||||
inputReplyToStory#5881323a peer:InputPeer story_id:int = InputReplyTo;
|
inputReplyToStory#5881323a peer:InputPeer story_id:int = InputReplyTo;
|
||||||
|
inputReplyToMonoForum#69d66c45 monoforum_peer_id:InputPeer = InputReplyTo;
|
||||||
exportedStoryLink#3fc9053b link:string = ExportedStoryLink;
|
exportedStoryLink#3fc9053b link:string = ExportedStoryLink;
|
||||||
storiesStealthMode#712e27fd flags:# active_until_date:flags.0?int cooldown_until_date:flags.1?int = StoriesStealthMode;
|
storiesStealthMode#712e27fd flags:# active_until_date:flags.0?int cooldown_until_date:flags.1?int = StoriesStealthMode;
|
||||||
mediaAreaCoordinates#cfc9e002 flags:# x:double y:double w:double h:double rotation:double radius:flags.0?double = MediaAreaCoordinates;
|
mediaAreaCoordinates#cfc9e002 flags:# x:double y:double w:double h:double rotation:double radius:flags.0?double = MediaAreaCoordinates;
|
||||||
@ -1280,6 +1283,7 @@ storyReactionPublicForward#bbab2643 message:Message = StoryReaction;
|
|||||||
storyReactionPublicRepost#cfcd0f13 peer_id:Peer story:StoryItem = StoryReaction;
|
storyReactionPublicRepost#cfcd0f13 peer_id:Peer story:StoryItem = StoryReaction;
|
||||||
stories.storyReactionsList#aa5f789c flags:# count:int reactions:Vector<StoryReaction> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryReactionsList;
|
stories.storyReactionsList#aa5f789c flags:# count:int reactions:Vector<StoryReaction> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryReactionsList;
|
||||||
savedDialog#bd87cb6c flags:# pinned:flags.2?true peer:Peer top_message:int = SavedDialog;
|
savedDialog#bd87cb6c flags:# pinned:flags.2?true peer:Peer top_message:int = SavedDialog;
|
||||||
|
monoForumDialog#64407ea7 flags:# unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_reactions_count:int draft:flags.1?DraftMessage = SavedDialog;
|
||||||
messages.savedDialogs#f83ae221 dialogs:Vector<SavedDialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.SavedDialogs;
|
messages.savedDialogs#f83ae221 dialogs:Vector<SavedDialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.SavedDialogs;
|
||||||
messages.savedDialogsSlice#44ba9dd9 count:int dialogs:Vector<SavedDialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.SavedDialogs;
|
messages.savedDialogsSlice#44ba9dd9 count:int dialogs:Vector<SavedDialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.SavedDialogs;
|
||||||
messages.savedDialogsNotModified#c01f6fe8 count:int = messages.SavedDialogs;
|
messages.savedDialogsNotModified#c01f6fe8 count:int = messages.SavedDialogs;
|
||||||
@ -1527,7 +1531,7 @@ messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
|
|||||||
messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool;
|
messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool;
|
||||||
messages.sendMessage#fbf2340a flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long = Updates;
|
messages.sendMessage#fbf2340a flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long = Updates;
|
||||||
messages.sendMedia#a550cd78 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long = Updates;
|
messages.sendMedia#a550cd78 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long = Updates;
|
||||||
messages.forwardMessages#bb9fa475 flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true allow_paid_floodskip:flags.19?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer top_msg_id:flags.9?int schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut video_timestamp:flags.20?int allow_paid_stars:flags.21?long = Updates;
|
messages.forwardMessages#38f0188c flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true allow_paid_floodskip:flags.19?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer top_msg_id:flags.9?int reply_to:flags.22?InputReplyTo schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut video_timestamp:flags.20?int allow_paid_stars:flags.21?long = Updates;
|
||||||
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
||||||
messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings;
|
messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings;
|
||||||
messages.report#fc78af9b peer:InputPeer id:Vector<int> option:bytes message:string = ReportResult;
|
messages.report#fc78af9b peer:InputPeer id:Vector<int> option:bytes message:string = ReportResult;
|
||||||
@ -1578,7 +1582,7 @@ messages.getUnreadMentions#f107e790 flags:# peer:InputPeer top_msg_id:flags.0?in
|
|||||||
messages.readMentions#36e5bf4d flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory;
|
messages.readMentions#36e5bf4d flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory;
|
||||||
messages.sendMultiMedia#1bf89d74 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo multi_media:Vector<InputSingleMedia> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long = Updates;
|
messages.sendMultiMedia#1bf89d74 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo multi_media:Vector<InputSingleMedia> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long = Updates;
|
||||||
messages.searchStickerSets#35705b8a flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets;
|
messages.searchStickerSets#35705b8a flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets;
|
||||||
messages.markDialogUnread#c286d98f flags:# unread:flags.0?true peer:InputDialogPeer = Bool;
|
messages.markDialogUnread#8c5006f8 flags:# unread:flags.0?true parent_peer:flags.1?InputPeer peer:InputDialogPeer = Bool;
|
||||||
messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true unpin:flags.1?true pm_oneside:flags.2?true peer:InputPeer id:int = Updates;
|
messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true unpin:flags.1?true pm_oneside:flags.2?true peer:InputPeer id:int = Updates;
|
||||||
messages.sendVote#10ea6184 peer:InputPeer msg_id:int options:Vector<bytes> = Updates;
|
messages.sendVote#10ea6184 peer:InputPeer msg_id:int options:Vector<bytes> = Updates;
|
||||||
messages.getOnlines#6e2be050 peer:InputPeer = ChatOnlines;
|
messages.getOnlines#6e2be050 peer:InputPeer = ChatOnlines;
|
||||||
@ -1599,7 +1603,7 @@ messages.updateDialogFiltersOrder#c563c1e4 order:Vector<int> = Bool;
|
|||||||
messages.getReplies#22ddd30c peer:InputPeer msg_id:int offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages;
|
messages.getReplies#22ddd30c peer:InputPeer msg_id:int offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages;
|
||||||
messages.getDiscussionMessage#446972fd peer:InputPeer msg_id:int = messages.DiscussionMessage;
|
messages.getDiscussionMessage#446972fd peer:InputPeer msg_id:int = messages.DiscussionMessage;
|
||||||
messages.readDiscussion#f731a9f4 peer:InputPeer msg_id:int read_max_id:int = Bool;
|
messages.readDiscussion#f731a9f4 peer:InputPeer msg_id:int read_max_id:int = Bool;
|
||||||
messages.unpinAllMessages#ee22b9a8 flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory;
|
messages.unpinAllMessages#62dd747 flags:# peer:InputPeer top_msg_id:flags.0?int saved_peer_id:flags.1?InputPeer = messages.AffectedHistory;
|
||||||
messages.deleteChat#5bd0ee50 chat_id:long = Bool;
|
messages.deleteChat#5bd0ee50 chat_id:long = Bool;
|
||||||
messages.getExportedChatInvites#a2b5a3f6 flags:# revoked:flags.3?true peer:InputPeer admin_id:InputUser offset_date:flags.2?int offset_link:flags.2?string limit:int = messages.ExportedChatInvites;
|
messages.getExportedChatInvites#a2b5a3f6 flags:# revoked:flags.3?true peer:InputPeer admin_id:InputUser offset_date:flags.2?int offset_link:flags.2?string limit:int = messages.ExportedChatInvites;
|
||||||
messages.editExportedChatInvite#bdca2f75 flags:# revoked:flags.2?true peer:InputPeer link:string expire_date:flags.0?int usage_limit:flags.1?int request_needed:flags.3?Bool title:flags.4?string = messages.ExportedChatInvite;
|
messages.editExportedChatInvite#bdca2f75 flags:# revoked:flags.2?true peer:InputPeer link:string expire_date:flags.0?int usage_limit:flags.1?int request_needed:flags.3?Bool title:flags.4?string = messages.ExportedChatInvite;
|
||||||
@ -1618,8 +1622,8 @@ messages.setChatAvailableReactions#864b2581 flags:# peer:InputPeer available_rea
|
|||||||
messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions;
|
messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions;
|
||||||
messages.setDefaultReaction#4f47a016 reaction:Reaction = Bool;
|
messages.setDefaultReaction#4f47a016 reaction:Reaction = Bool;
|
||||||
messages.translateText#63183030 flags:# peer:flags.0?InputPeer id:flags.0?Vector<int> text:flags.1?Vector<TextWithEntities> to_lang:string = messages.TranslatedText;
|
messages.translateText#63183030 flags:# peer:flags.0?InputPeer id:flags.0?Vector<int> text:flags.1?Vector<TextWithEntities> to_lang:string = messages.TranslatedText;
|
||||||
messages.getUnreadReactions#3223495b flags:# peer:InputPeer top_msg_id:flags.0?int offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
messages.getUnreadReactions#bd7f90ac flags:# peer:InputPeer top_msg_id:flags.0?int saved_peer_id:flags.1?InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||||
messages.readReactions#54aa7f8e flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory;
|
messages.readReactions#9ec44f93 flags:# peer:InputPeer top_msg_id:flags.0?int saved_peer_id:flags.1?InputPeer = messages.AffectedHistory;
|
||||||
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
|
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
|
||||||
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
|
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
|
||||||
messages.toggleBotInAttachMenu#69f59d69 flags:# write_allowed:flags.0?true bot:InputUser enabled:Bool = Bool;
|
messages.toggleBotInAttachMenu#69f59d69 flags:# write_allowed:flags.0?true bot:InputUser enabled:Bool = Bool;
|
||||||
@ -1639,9 +1643,9 @@ messages.getExtendedMedia#84f80814 peer:InputPeer id:Vector<int> = Updates;
|
|||||||
messages.togglePeerTranslations#e47cb579 flags:# disabled:flags.0?true peer:InputPeer = Bool;
|
messages.togglePeerTranslations#e47cb579 flags:# disabled:flags.0?true peer:InputPeer = Bool;
|
||||||
messages.getBotApp#34fdc5c3 app:InputBotApp hash:long = messages.BotApp;
|
messages.getBotApp#34fdc5c3 app:InputBotApp hash:long = messages.BotApp;
|
||||||
messages.requestAppWebView#53618bce flags:# write_allowed:flags.0?true compact:flags.7?true fullscreen:flags.8?true peer:InputPeer app:InputBotApp start_param:flags.1?string theme_params:flags.2?DataJSON platform:string = WebViewResult;
|
messages.requestAppWebView#53618bce flags:# write_allowed:flags.0?true compact:flags.7?true fullscreen:flags.8?true peer:InputPeer app:InputBotApp start_param:flags.1?string theme_params:flags.2?DataJSON platform:string = WebViewResult;
|
||||||
messages.getSavedDialogs#5381d21a flags:# exclude_pinned:flags.0?true offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:long = messages.SavedDialogs;
|
messages.getSavedDialogs#1e91fc99 flags:# exclude_pinned:flags.0?true parent_peer:flags.1?InputPeer offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:long = messages.SavedDialogs;
|
||||||
messages.getSavedHistory#3d9a414d peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages;
|
messages.getSavedHistory#998ab009 flags:# parent_peer:flags.0?InputPeer peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages;
|
||||||
messages.deleteSavedHistory#6e98102b flags:# peer:InputPeer max_id:int min_date:flags.2?int max_date:flags.3?int = messages.AffectedHistory;
|
messages.deleteSavedHistory#4dc5085f flags:# parent_peer:flags.0?InputPeer peer:InputPeer max_id:int min_date:flags.2?int max_date:flags.3?int = messages.AffectedHistory;
|
||||||
messages.getPinnedSavedDialogs#d63d94e0 = messages.SavedDialogs;
|
messages.getPinnedSavedDialogs#d63d94e0 = messages.SavedDialogs;
|
||||||
messages.toggleSavedDialogPin#ac81bbde flags:# pinned:flags.0?true peer:InputDialogPeer = Bool;
|
messages.toggleSavedDialogPin#ac81bbde flags:# pinned:flags.0?true peer:InputDialogPeer = Bool;
|
||||||
messages.getSavedReactionTags#3637e05b flags:# peer:flags.0?InputPeer hash:long = messages.SavedReactionTags;
|
messages.getSavedReactionTags#3637e05b flags:# peer:flags.0?InputPeer hash:long = messages.SavedReactionTags;
|
||||||
@ -1715,7 +1719,7 @@ channels.toggleJoinRequest#4c2985b6 channel:InputChannel enabled:Bool = Updates;
|
|||||||
channels.reorderUsernames#b45ced1d channel:InputChannel order:Vector<string> = Bool;
|
channels.reorderUsernames#b45ced1d channel:InputChannel order:Vector<string> = Bool;
|
||||||
channels.toggleUsername#50f24105 channel:InputChannel username:string active:Bool = Bool;
|
channels.toggleUsername#50f24105 channel:InputChannel username:string active:Bool = Bool;
|
||||||
channels.deactivateAllUsernames#a245dd3 channel:InputChannel = Bool;
|
channels.deactivateAllUsernames#a245dd3 channel:InputChannel = Bool;
|
||||||
channels.toggleForum#a4298b29 channel:InputChannel enabled:Bool = Updates;
|
channels.toggleForum#3ff75734 channel:InputChannel enabled:Bool tabs:Bool = Updates;
|
||||||
channels.createForumTopic#f40c0224 flags:# channel:InputChannel title:string icon_color:flags.0?int icon_emoji_id:flags.3?long random_id:long send_as:flags.2?InputPeer = Updates;
|
channels.createForumTopic#f40c0224 flags:# channel:InputChannel title:string icon_color:flags.0?int icon_emoji_id:flags.3?long random_id:long send_as:flags.2?InputPeer = Updates;
|
||||||
channels.getForumTopics#de560d1 flags:# channel:InputChannel q:flags.0?string offset_date:int offset_id:int offset_topic:int limit:int = messages.ForumTopics;
|
channels.getForumTopics#de560d1 flags:# channel:InputChannel q:flags.0?string offset_date:int offset_id:int offset_topic:int limit:int = messages.ForumTopics;
|
||||||
channels.getForumTopicsByID#b0831eb9 channel:InputChannel topics:Vector<int> = messages.ForumTopics;
|
channels.getForumTopicsByID#b0831eb9 channel:InputChannel topics:Vector<int> = messages.ForumTopics;
|
||||||
@ -1726,7 +1730,7 @@ channels.toggleParticipantsHidden#6a6e7854 channel:InputChannel enabled:Bool = U
|
|||||||
channels.toggleViewForumAsMessages#9738bb15 channel:InputChannel enabled:Bool = Updates;
|
channels.toggleViewForumAsMessages#9738bb15 channel:InputChannel enabled:Bool = Updates;
|
||||||
channels.getChannelRecommendations#25a71742 flags:# channel:flags.0?InputChannel = messages.Chats;
|
channels.getChannelRecommendations#25a71742 flags:# channel:flags.0?InputChannel = messages.Chats;
|
||||||
channels.searchPosts#d19f987b hashtag:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
channels.searchPosts#d19f987b hashtag:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
||||||
channels.updatePaidMessagesPrice#fc84653f channel:InputChannel send_paid_messages_stars:long = Updates;
|
channels.updatePaidMessagesPrice#4b12327b flags:# broadcast_messages_allowed:flags.0?true channel:InputChannel send_paid_messages_stars:long = Updates;
|
||||||
channels.toggleAutotranslation#167fc0a1 channel:InputChannel enabled:Bool = Updates;
|
channels.toggleAutotranslation#167fc0a1 channel:InputChannel enabled:Bool = Updates;
|
||||||
bots.setBotInfo#10cf3123 flags:# bot:flags.2?InputUser lang_code:string name:flags.3?string about:flags.0?string description:flags.1?string = Bool;
|
bots.setBotInfo#10cf3123 flags:# bot:flags.2?InputUser lang_code:string name:flags.3?string about:flags.0?string description:flags.1?string = Bool;
|
||||||
bots.canSendMessage#1359f4e6 bot:InputUser = Bool;
|
bots.canSendMessage#1359f4e6 bot:InputUser = Bool;
|
||||||
|
|||||||
@ -99,7 +99,7 @@ userStatusLastMonth#65899777 flags:# by_me:flags.0?true = UserStatus;
|
|||||||
chatEmpty#29562865 id:long = Chat;
|
chatEmpty#29562865 id:long = Chat;
|
||||||
chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
|
chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
|
||||||
chatForbidden#6592a1a7 id:long title:string = Chat;
|
chatForbidden#6592a1a7 id:long title:string = Chat;
|
||||||
channel#7482147e 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 signature_profiles:flags2.12?true autotranslation:flags2.15?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 subscription_until_date:flags2.11?int bot_verification_icon:flags2.13?long send_paid_messages_stars:flags2.14?long = Chat;
|
channel#fe685355 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 signature_profiles:flags2.12?true autotranslation:flags2.15?true broadcast_messages_allowed:flags2.16?true monoforum:flags2.17?true forum_tabs:flags2.19?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 subscription_until_date:flags2.11?int bot_verification_icon:flags2.13?long send_paid_messages_stars:flags2.14?long linked_monoforum_id:flags2.18?long = Chat;
|
||||||
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
|
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
|
||||||
|
|
||||||
chatFull#2633421b 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 reactions_limit:flags.20?int = ChatFull;
|
chatFull#2633421b 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 reactions_limit:flags.20?int = ChatFull;
|
||||||
@ -186,7 +186,7 @@ messageActionPrizeStars#b00c47a2 flags:# unclaimed:flags.0?true stars:long trans
|
|||||||
messageActionStarGift#4717e8a4 flags:# name_hidden:flags.0?true saved:flags.2?true converted:flags.3?true upgraded:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true gift:StarGift message:flags.1?TextWithEntities convert_stars:flags.4?long upgrade_msg_id:flags.5?int upgrade_stars:flags.8?long from_id:flags.11?Peer peer:flags.12?Peer saved_id:flags.12?long = MessageAction;
|
messageActionStarGift#4717e8a4 flags:# name_hidden:flags.0?true saved:flags.2?true converted:flags.3?true upgraded:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true gift:StarGift message:flags.1?TextWithEntities convert_stars:flags.4?long upgrade_msg_id:flags.5?int upgrade_stars:flags.8?long from_id:flags.11?Peer peer:flags.12?Peer saved_id:flags.12?long = MessageAction;
|
||||||
messageActionStarGiftUnique#2e3ae60e flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long from_id:flags.6?Peer peer:flags.7?Peer saved_id:flags.7?long resale_stars:flags.8?long can_transfer_at:flags.9?int can_resell_at:flags.10?int = MessageAction;
|
messageActionStarGiftUnique#2e3ae60e flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long from_id:flags.6?Peer peer:flags.7?Peer saved_id:flags.7?long resale_stars:flags.8?long can_transfer_at:flags.9?int can_resell_at:flags.10?int = MessageAction;
|
||||||
messageActionPaidMessagesRefunded#ac1f1fcd count:int stars:long = MessageAction;
|
messageActionPaidMessagesRefunded#ac1f1fcd count:int stars:long = MessageAction;
|
||||||
messageActionPaidMessagesPrice#bcd71419 stars:long = MessageAction;
|
messageActionPaidMessagesPrice#84b88578 flags:# broadcast_messages_allowed:flags.0?true stars:long = MessageAction;
|
||||||
messageActionConferenceCall#2ffe2f7a flags:# missed:flags.0?true active:flags.1?true video:flags.4?true call_id:long duration:flags.2?int other_participants:flags.3?Vector<Peer> = MessageAction;
|
messageActionConferenceCall#2ffe2f7a flags:# missed:flags.0?true active:flags.1?true video:flags.4?true call_id:long duration:flags.2?int other_participants:flags.3?Vector<Peer> = MessageAction;
|
||||||
|
|
||||||
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
||||||
@ -332,7 +332,7 @@ updateBotCallbackQuery#b9cfc48d flags:# query_id:long user_id:long peer:Peer msg
|
|||||||
updateEditMessage#e40370a3 message:Message pts:int pts_count:int = Update;
|
updateEditMessage#e40370a3 message:Message pts:int pts_count:int = Update;
|
||||||
updateInlineBotCallbackQuery#691e9052 flags:# query_id:long user_id:long msg_id:InputBotInlineMessageID chat_instance:long data:flags.0?bytes game_short_name:flags.1?string = Update;
|
updateInlineBotCallbackQuery#691e9052 flags:# query_id:long user_id:long msg_id:InputBotInlineMessageID chat_instance:long data:flags.0?bytes game_short_name:flags.1?string = Update;
|
||||||
updateReadChannelOutbox#b75f99a9 channel_id:long max_id:int = Update;
|
updateReadChannelOutbox#b75f99a9 channel_id:long max_id:int = Update;
|
||||||
updateDraftMessage#1b49ec6d flags:# peer:Peer top_msg_id:flags.0?int draft:DraftMessage = Update;
|
updateDraftMessage#edfc111e flags:# peer:Peer top_msg_id:flags.0?int saved_peer_id:flags.1?Peer draft:DraftMessage = Update;
|
||||||
updateReadFeaturedStickers#571d2742 = Update;
|
updateReadFeaturedStickers#571d2742 = Update;
|
||||||
updateRecentStickers#9a422c20 = Update;
|
updateRecentStickers#9a422c20 = Update;
|
||||||
updateConfig#a229dd06 = Update;
|
updateConfig#a229dd06 = Update;
|
||||||
@ -348,10 +348,10 @@ updatePhoneCall#ab0f6b1e phone_call:PhoneCall = Update;
|
|||||||
updateLangPackTooLong#46560264 lang_code:string = Update;
|
updateLangPackTooLong#46560264 lang_code:string = Update;
|
||||||
updateLangPack#56022f4d difference:LangPackDifference = Update;
|
updateLangPack#56022f4d difference:LangPackDifference = Update;
|
||||||
updateFavedStickers#e511996d = Update;
|
updateFavedStickers#e511996d = Update;
|
||||||
updateChannelReadMessagesContents#ea29055d flags:# channel_id:long top_msg_id:flags.0?int messages:Vector<int> = Update;
|
updateChannelReadMessagesContents#25f324f7 flags:# channel_id:long top_msg_id:flags.0?int saved_peer_id:flags.1?Peer messages:Vector<int> = Update;
|
||||||
updateContactsReset#7084a7be = Update;
|
updateContactsReset#7084a7be = Update;
|
||||||
updateChannelAvailableMessages#b23fc698 channel_id:long available_min_id:int = Update;
|
updateChannelAvailableMessages#b23fc698 channel_id:long available_min_id:int = Update;
|
||||||
updateDialogUnreadMark#e16459c3 flags:# unread:flags.0?true peer:DialogPeer = Update;
|
updateDialogUnreadMark#b658f23e flags:# unread:flags.0?true peer:DialogPeer saved_peer_id:flags.1?Peer = Update;
|
||||||
updateMessagePoll#aca1657b flags:# poll_id:long poll:flags.0?Poll results:PollResults = Update;
|
updateMessagePoll#aca1657b flags:# poll_id:long poll:flags.0?Poll results:PollResults = Update;
|
||||||
updateChatDefaultBannedRights#54c01850 peer:Peer default_banned_rights:ChatBannedRights version:int = Update;
|
updateChatDefaultBannedRights#54c01850 peer:Peer default_banned_rights:ChatBannedRights version:int = Update;
|
||||||
updateFolderPeers#19360dc0 folder_peers:Vector<FolderPeer> pts:int pts_count:int = Update;
|
updateFolderPeers#19360dc0 folder_peers:Vector<FolderPeer> pts:int pts_count:int = Update;
|
||||||
@ -385,7 +385,7 @@ updateGroupCallConnection#b783982 flags:# presentation:flags.0?true params:DataJ
|
|||||||
updateBotCommands#4d712f2e peer:Peer bot_id:long commands:Vector<BotCommand> = Update;
|
updateBotCommands#4d712f2e peer:Peer bot_id:long commands:Vector<BotCommand> = Update;
|
||||||
updatePendingJoinRequests#7063c3db peer:Peer requests_pending:int recent_requesters:Vector<long> = Update;
|
updatePendingJoinRequests#7063c3db peer:Peer requests_pending:int recent_requesters:Vector<long> = Update;
|
||||||
updateBotChatInviteRequester#11dfa986 peer:Peer date:int user_id:long about:string invite:ExportedChatInvite qts:int = Update;
|
updateBotChatInviteRequester#11dfa986 peer:Peer date:int user_id:long about:string invite:ExportedChatInvite qts:int = Update;
|
||||||
updateMessageReactions#5e1b3cb8 flags:# peer:Peer msg_id:int top_msg_id:flags.0?int reactions:MessageReactions = Update;
|
updateMessageReactions#1e297bfa flags:# peer:Peer msg_id:int top_msg_id:flags.0?int saved_peer_id:flags.1?Peer reactions:MessageReactions = Update;
|
||||||
updateAttachMenuBots#17b7a20b = Update;
|
updateAttachMenuBots#17b7a20b = Update;
|
||||||
updateWebViewResultSent#1592b79d query_id:long = Update;
|
updateWebViewResultSent#1592b79d query_id:long = Update;
|
||||||
updateBotMenuButton#14b85813 bot_id:long button:BotMenuButton = Update;
|
updateBotMenuButton#14b85813 bot_id:long button:BotMenuButton = Update;
|
||||||
@ -433,6 +433,8 @@ updateBotPurchasedPaidMedia#283bd312 user_id:long payload:string qts:int = Updat
|
|||||||
updatePaidReactionPrivacy#8b725fce private:PaidReactionPrivacy = Update;
|
updatePaidReactionPrivacy#8b725fce private:PaidReactionPrivacy = Update;
|
||||||
updateSentPhoneCode#504aa18f sent_code:auth.SentCode = Update;
|
updateSentPhoneCode#504aa18f sent_code:auth.SentCode = Update;
|
||||||
updateGroupCallChainBlocks#a477288f call:InputGroupCall sub_chain_id:int blocks:Vector<bytes> next_offset:int = Update;
|
updateGroupCallChainBlocks#a477288f call:InputGroupCall sub_chain_id:int blocks:Vector<bytes> next_offset:int = Update;
|
||||||
|
updateReadMonoForumInbox#77b0e372 channel_id:long saved_peer_id:Peer read_max_id:int = Update;
|
||||||
|
updateReadMonoForumOutbox#a4a79376 channel_id:long saved_peer_id:Peer read_max_id:int = Update;
|
||||||
|
|
||||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||||
|
|
||||||
@ -1638,8 +1640,9 @@ stories.storyViewsList#59d78fc5 flags:# count:int views_count:int forwards_count
|
|||||||
|
|
||||||
stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews;
|
stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews;
|
||||||
|
|
||||||
inputReplyToMessage#22c0f6d5 flags:# reply_to_msg_id:int top_msg_id:flags.0?int reply_to_peer_id:flags.1?InputPeer quote_text:flags.2?string quote_entities:flags.3?Vector<MessageEntity> quote_offset:flags.4?int = InputReplyTo;
|
inputReplyToMessage#b07038b0 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 monoforum_peer_id:flags.5?InputPeer = InputReplyTo;
|
||||||
inputReplyToStory#5881323a peer:InputPeer story_id:int = InputReplyTo;
|
inputReplyToStory#5881323a peer:InputPeer story_id:int = InputReplyTo;
|
||||||
|
inputReplyToMonoForum#69d66c45 monoforum_peer_id:InputPeer = InputReplyTo;
|
||||||
|
|
||||||
exportedStoryLink#3fc9053b link:string = ExportedStoryLink;
|
exportedStoryLink#3fc9053b link:string = ExportedStoryLink;
|
||||||
|
|
||||||
@ -1712,6 +1715,7 @@ storyReactionPublicRepost#cfcd0f13 peer_id:Peer story:StoryItem = StoryReaction;
|
|||||||
stories.storyReactionsList#aa5f789c flags:# count:int reactions:Vector<StoryReaction> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryReactionsList;
|
stories.storyReactionsList#aa5f789c flags:# count:int reactions:Vector<StoryReaction> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryReactionsList;
|
||||||
|
|
||||||
savedDialog#bd87cb6c flags:# pinned:flags.2?true peer:Peer top_message:int = SavedDialog;
|
savedDialog#bd87cb6c flags:# pinned:flags.2?true peer:Peer top_message:int = SavedDialog;
|
||||||
|
monoForumDialog#64407ea7 flags:# unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_reactions_count:int draft:flags.1?DraftMessage = SavedDialog;
|
||||||
|
|
||||||
messages.savedDialogs#f83ae221 dialogs:Vector<SavedDialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.SavedDialogs;
|
messages.savedDialogs#f83ae221 dialogs:Vector<SavedDialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.SavedDialogs;
|
||||||
messages.savedDialogsSlice#44ba9dd9 count:int dialogs:Vector<SavedDialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.SavedDialogs;
|
messages.savedDialogsSlice#44ba9dd9 count:int dialogs:Vector<SavedDialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.SavedDialogs;
|
||||||
@ -2177,7 +2181,7 @@ messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
|
|||||||
messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool;
|
messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool;
|
||||||
messages.sendMessage#fbf2340a flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long = Updates;
|
messages.sendMessage#fbf2340a flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long = Updates;
|
||||||
messages.sendMedia#a550cd78 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long = Updates;
|
messages.sendMedia#a550cd78 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long = Updates;
|
||||||
messages.forwardMessages#bb9fa475 flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true allow_paid_floodskip:flags.19?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer top_msg_id:flags.9?int schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut video_timestamp:flags.20?int allow_paid_stars:flags.21?long = Updates;
|
messages.forwardMessages#38f0188c flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true allow_paid_floodskip:flags.19?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer top_msg_id:flags.9?int reply_to:flags.22?InputReplyTo schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut video_timestamp:flags.20?int allow_paid_stars:flags.21?long = Updates;
|
||||||
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
||||||
messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings;
|
messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings;
|
||||||
messages.report#fc78af9b peer:InputPeer id:Vector<int> option:bytes message:string = ReportResult;
|
messages.report#fc78af9b peer:InputPeer id:Vector<int> option:bytes message:string = ReportResult;
|
||||||
@ -2259,8 +2263,8 @@ messages.sendMultiMedia#1bf89d74 flags:# silent:flags.5?true background:flags.6?
|
|||||||
messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile;
|
messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile;
|
||||||
messages.searchStickerSets#35705b8a flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets;
|
messages.searchStickerSets#35705b8a flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets;
|
||||||
messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
|
messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
|
||||||
messages.markDialogUnread#c286d98f flags:# unread:flags.0?true peer:InputDialogPeer = Bool;
|
messages.markDialogUnread#8c5006f8 flags:# unread:flags.0?true parent_peer:flags.1?InputPeer peer:InputDialogPeer = Bool;
|
||||||
messages.getDialogUnreadMarks#22e24e22 = Vector<DialogPeer>;
|
messages.getDialogUnreadMarks#21202222 flags:# parent_peer:flags.0?InputPeer = Vector<DialogPeer>;
|
||||||
messages.clearAllDrafts#7e58ee9c = Bool;
|
messages.clearAllDrafts#7e58ee9c = Bool;
|
||||||
messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true unpin:flags.1?true pm_oneside:flags.2?true peer:InputPeer id:int = Updates;
|
messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true unpin:flags.1?true pm_oneside:flags.2?true peer:InputPeer id:int = Updates;
|
||||||
messages.sendVote#10ea6184 peer:InputPeer msg_id:int options:Vector<bytes> = Updates;
|
messages.sendVote#10ea6184 peer:InputPeer msg_id:int options:Vector<bytes> = Updates;
|
||||||
@ -2290,7 +2294,7 @@ messages.getOldFeaturedStickers#7ed094a1 offset:int limit:int hash:long = messag
|
|||||||
messages.getReplies#22ddd30c peer:InputPeer msg_id:int offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages;
|
messages.getReplies#22ddd30c peer:InputPeer msg_id:int offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages;
|
||||||
messages.getDiscussionMessage#446972fd peer:InputPeer msg_id:int = messages.DiscussionMessage;
|
messages.getDiscussionMessage#446972fd peer:InputPeer msg_id:int = messages.DiscussionMessage;
|
||||||
messages.readDiscussion#f731a9f4 peer:InputPeer msg_id:int read_max_id:int = Bool;
|
messages.readDiscussion#f731a9f4 peer:InputPeer msg_id:int read_max_id:int = Bool;
|
||||||
messages.unpinAllMessages#ee22b9a8 flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory;
|
messages.unpinAllMessages#62dd747 flags:# peer:InputPeer top_msg_id:flags.0?int saved_peer_id:flags.1?InputPeer = messages.AffectedHistory;
|
||||||
messages.deleteChat#5bd0ee50 chat_id:long = Bool;
|
messages.deleteChat#5bd0ee50 chat_id:long = Bool;
|
||||||
messages.deletePhoneCallHistory#f9cbe409 flags:# revoke:flags.0?true = messages.AffectedFoundMessages;
|
messages.deletePhoneCallHistory#f9cbe409 flags:# revoke:flags.0?true = messages.AffectedFoundMessages;
|
||||||
messages.checkHistoryImport#43fe19f3 import_head:string = messages.HistoryImportParsed;
|
messages.checkHistoryImport#43fe19f3 import_head:string = messages.HistoryImportParsed;
|
||||||
@ -2321,8 +2325,8 @@ messages.setChatAvailableReactions#864b2581 flags:# peer:InputPeer available_rea
|
|||||||
messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions;
|
messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions;
|
||||||
messages.setDefaultReaction#4f47a016 reaction:Reaction = Bool;
|
messages.setDefaultReaction#4f47a016 reaction:Reaction = Bool;
|
||||||
messages.translateText#63183030 flags:# peer:flags.0?InputPeer id:flags.0?Vector<int> text:flags.1?Vector<TextWithEntities> to_lang:string = messages.TranslatedText;
|
messages.translateText#63183030 flags:# peer:flags.0?InputPeer id:flags.0?Vector<int> text:flags.1?Vector<TextWithEntities> to_lang:string = messages.TranslatedText;
|
||||||
messages.getUnreadReactions#3223495b flags:# peer:InputPeer top_msg_id:flags.0?int offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
messages.getUnreadReactions#bd7f90ac flags:# peer:InputPeer top_msg_id:flags.0?int saved_peer_id:flags.1?InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||||
messages.readReactions#54aa7f8e flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory;
|
messages.readReactions#9ec44f93 flags:# peer:InputPeer top_msg_id:flags.0?int saved_peer_id:flags.1?InputPeer = messages.AffectedHistory;
|
||||||
messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = messages.Messages;
|
messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = messages.Messages;
|
||||||
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
|
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
|
||||||
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
|
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
|
||||||
@ -2354,9 +2358,9 @@ messages.getBotApp#34fdc5c3 app:InputBotApp hash:long = messages.BotApp;
|
|||||||
messages.requestAppWebView#53618bce flags:# write_allowed:flags.0?true compact:flags.7?true fullscreen:flags.8?true peer:InputPeer app:InputBotApp start_param:flags.1?string theme_params:flags.2?DataJSON platform:string = WebViewResult;
|
messages.requestAppWebView#53618bce flags:# write_allowed:flags.0?true compact:flags.7?true fullscreen:flags.8?true peer:InputPeer app:InputBotApp start_param:flags.1?string theme_params:flags.2?DataJSON platform:string = WebViewResult;
|
||||||
messages.setChatWallPaper#8ffacae1 flags:# for_both:flags.3?true revert:flags.4?true peer:InputPeer wallpaper:flags.0?InputWallPaper settings:flags.2?WallPaperSettings id:flags.1?int = Updates;
|
messages.setChatWallPaper#8ffacae1 flags:# for_both:flags.3?true revert:flags.4?true peer:InputPeer wallpaper:flags.0?InputWallPaper settings:flags.2?WallPaperSettings id:flags.1?int = Updates;
|
||||||
messages.searchEmojiStickerSets#92b4494c flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets;
|
messages.searchEmojiStickerSets#92b4494c flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets;
|
||||||
messages.getSavedDialogs#5381d21a flags:# exclude_pinned:flags.0?true offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:long = messages.SavedDialogs;
|
messages.getSavedDialogs#1e91fc99 flags:# exclude_pinned:flags.0?true parent_peer:flags.1?InputPeer offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:long = messages.SavedDialogs;
|
||||||
messages.getSavedHistory#3d9a414d peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages;
|
messages.getSavedHistory#998ab009 flags:# parent_peer:flags.0?InputPeer peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages;
|
||||||
messages.deleteSavedHistory#6e98102b flags:# peer:InputPeer max_id:int min_date:flags.2?int max_date:flags.3?int = messages.AffectedHistory;
|
messages.deleteSavedHistory#4dc5085f flags:# parent_peer:flags.0?InputPeer peer:InputPeer max_id:int min_date:flags.2?int max_date:flags.3?int = messages.AffectedHistory;
|
||||||
messages.getPinnedSavedDialogs#d63d94e0 = messages.SavedDialogs;
|
messages.getPinnedSavedDialogs#d63d94e0 = messages.SavedDialogs;
|
||||||
messages.toggleSavedDialogPin#ac81bbde flags:# pinned:flags.0?true peer:InputDialogPeer = Bool;
|
messages.toggleSavedDialogPin#ac81bbde flags:# pinned:flags.0?true peer:InputDialogPeer = Bool;
|
||||||
messages.reorderPinnedSavedDialogs#8b716587 flags:# force:flags.0?true order:Vector<InputDialogPeer> = Bool;
|
messages.reorderPinnedSavedDialogs#8b716587 flags:# force:flags.0?true order:Vector<InputDialogPeer> = Bool;
|
||||||
@ -2391,6 +2395,8 @@ messages.savePreparedInlineMessage#f21f7f2f flags:# result:InputBotInlineResult
|
|||||||
messages.getPreparedInlineMessage#857ebdb8 bot:InputUser id:string = messages.PreparedInlineMessage;
|
messages.getPreparedInlineMessage#857ebdb8 bot:InputUser id:string = messages.PreparedInlineMessage;
|
||||||
messages.searchStickers#29b1c66a flags:# emojis:flags.0?true q:string emoticon:string lang_code:Vector<string> offset:int limit:int hash:long = messages.FoundStickers;
|
messages.searchStickers#29b1c66a flags:# emojis:flags.0?true q:string emoticon:string lang_code:Vector<string> offset:int limit:int hash:long = messages.FoundStickers;
|
||||||
messages.reportMessagesDelivery#5a6d7395 flags:# push:flags.0?true peer:InputPeer id:Vector<int> = Bool;
|
messages.reportMessagesDelivery#5a6d7395 flags:# push:flags.0?true peer:InputPeer id:Vector<int> = Bool;
|
||||||
|
messages.getSavedDialogsByID#6f6f9c96 flags:# parent_peer:flags.1?InputPeer ids:Vector<InputPeer> = messages.SavedDialogs;
|
||||||
|
messages.readSavedHistory#ba4a3b5b parent_peer:InputPeer peer:InputPeer max_id:int = Bool;
|
||||||
|
|
||||||
updates.getState#edd4882a = updates.State;
|
updates.getState#edd4882a = updates.State;
|
||||||
updates.getDifference#19c2f763 flags:# pts:int pts_limit:flags.1?int pts_total_limit:flags.0?int date:int qts:int qts_limit:flags.2?int = updates.Difference;
|
updates.getDifference#19c2f763 flags:# pts:int pts_limit:flags.1?int pts_total_limit:flags.0?int date:int qts:int qts_limit:flags.2?int = updates.Difference;
|
||||||
@ -2479,7 +2485,7 @@ channels.toggleJoinRequest#4c2985b6 channel:InputChannel enabled:Bool = Updates;
|
|||||||
channels.reorderUsernames#b45ced1d channel:InputChannel order:Vector<string> = Bool;
|
channels.reorderUsernames#b45ced1d channel:InputChannel order:Vector<string> = Bool;
|
||||||
channels.toggleUsername#50f24105 channel:InputChannel username:string active:Bool = Bool;
|
channels.toggleUsername#50f24105 channel:InputChannel username:string active:Bool = Bool;
|
||||||
channels.deactivateAllUsernames#a245dd3 channel:InputChannel = Bool;
|
channels.deactivateAllUsernames#a245dd3 channel:InputChannel = Bool;
|
||||||
channels.toggleForum#a4298b29 channel:InputChannel enabled:Bool = Updates;
|
channels.toggleForum#3ff75734 channel:InputChannel enabled:Bool tabs:Bool = Updates;
|
||||||
channels.createForumTopic#f40c0224 flags:# channel:InputChannel title:string icon_color:flags.0?int icon_emoji_id:flags.3?long random_id:long send_as:flags.2?InputPeer = Updates;
|
channels.createForumTopic#f40c0224 flags:# channel:InputChannel title:string icon_color:flags.0?int icon_emoji_id:flags.3?long random_id:long send_as:flags.2?InputPeer = Updates;
|
||||||
channels.getForumTopics#de560d1 flags:# channel:InputChannel q:flags.0?string offset_date:int offset_id:int offset_topic:int limit:int = messages.ForumTopics;
|
channels.getForumTopics#de560d1 flags:# channel:InputChannel q:flags.0?string offset_date:int offset_id:int offset_topic:int limit:int = messages.ForumTopics;
|
||||||
channels.getForumTopicsByID#b0831eb9 channel:InputChannel topics:Vector<int> = messages.ForumTopics;
|
channels.getForumTopicsByID#b0831eb9 channel:InputChannel topics:Vector<int> = messages.ForumTopics;
|
||||||
@ -2498,8 +2504,9 @@ channels.setBoostsToUnblockRestrictions#ad399cee channel:InputChannel boosts:int
|
|||||||
channels.setEmojiStickers#3cd930b7 channel:InputChannel stickerset:InputStickerSet = Bool;
|
channels.setEmojiStickers#3cd930b7 channel:InputChannel stickerset:InputStickerSet = Bool;
|
||||||
channels.restrictSponsoredMessages#9ae91519 channel:InputChannel restricted:Bool = Updates;
|
channels.restrictSponsoredMessages#9ae91519 channel:InputChannel restricted:Bool = Updates;
|
||||||
channels.searchPosts#d19f987b hashtag:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
channels.searchPosts#d19f987b hashtag:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
||||||
channels.updatePaidMessagesPrice#fc84653f channel:InputChannel send_paid_messages_stars:long = Updates;
|
channels.updatePaidMessagesPrice#4b12327b flags:# broadcast_messages_allowed:flags.0?true channel:InputChannel send_paid_messages_stars:long = Updates;
|
||||||
channels.toggleAutotranslation#167fc0a1 channel:InputChannel enabled:Bool = Updates;
|
channels.toggleAutotranslation#167fc0a1 channel:InputChannel enabled:Bool = Updates;
|
||||||
|
channels.getMessageAuthor#ece2a0e6 channel:InputChannel id:int = User;
|
||||||
|
|
||||||
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
|
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
|
||||||
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
|
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
|
||||||
|
|||||||
31
src/types/language.d.ts
vendored
31
src/types/language.d.ts
vendored
@ -1509,7 +1509,7 @@ export interface LangPair {
|
|||||||
'FrozenAccountAppealTitle': undefined;
|
'FrozenAccountAppealTitle': undefined;
|
||||||
'ButtonAppeal': undefined;
|
'ButtonAppeal': undefined;
|
||||||
'ButtonUnderstood': undefined;
|
'ButtonUnderstood': undefined;
|
||||||
'ActionPaidMessageGroupPriceFree': undefined;
|
'ActionPaidMessagePriceFreeYou': undefined;
|
||||||
'NotificationTitleNotSupportedInFrozenAccount': undefined;
|
'NotificationTitleNotSupportedInFrozenAccount': undefined;
|
||||||
'NotificationMessageNotSupportedInFrozenAccount': undefined;
|
'NotificationMessageNotSupportedInFrozenAccount': undefined;
|
||||||
'GiftRibbonSale': undefined;
|
'GiftRibbonSale': undefined;
|
||||||
@ -1530,6 +1530,10 @@ export interface LangPair {
|
|||||||
'ValueGiftSortByNumber': undefined;
|
'ValueGiftSortByNumber': undefined;
|
||||||
'ResellGiftsNoFound': undefined;
|
'ResellGiftsNoFound': undefined;
|
||||||
'ResellGiftsClearFilters': undefined;
|
'ResellGiftsClearFilters': undefined;
|
||||||
|
'MonoforumBadge': undefined;
|
||||||
|
'MonoforumStatus': undefined;
|
||||||
|
'MonoforumComposerPlaceholder': undefined;
|
||||||
|
'ChannelSendMessage': undefined;
|
||||||
'AutomaticTranslation': undefined;
|
'AutomaticTranslation': undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2393,8 +2397,12 @@ export interface LangPairWithVariables<V = LangVariable> {
|
|||||||
'percent': V;
|
'percent': V;
|
||||||
'amount': V;
|
'amount': V;
|
||||||
};
|
};
|
||||||
'FirstMessageInPaidMessagesChat': {
|
'MessagesPlaceholderPaidUser': {
|
||||||
'user': V;
|
'peer': V;
|
||||||
|
'amount': V;
|
||||||
|
};
|
||||||
|
'MessagesPlaceholderPaidChannel': {
|
||||||
|
'peer': V;
|
||||||
'amount': V;
|
'amount': V;
|
||||||
};
|
};
|
||||||
'ComposerPlaceholderPaidMessage': {
|
'ComposerPlaceholderPaidMessage': {
|
||||||
@ -2434,8 +2442,21 @@ export interface LangPairWithVariables<V = LangVariable> {
|
|||||||
'botLink': V;
|
'botLink': V;
|
||||||
'date': V;
|
'date': V;
|
||||||
};
|
};
|
||||||
'ActionPaidMessageGroupPrice': {
|
'ActionPaidMessagePrice': {
|
||||||
'stars': V;
|
'peer': V;
|
||||||
|
'amount': V;
|
||||||
|
};
|
||||||
|
'ActionPaidMessagePriceYou': {
|
||||||
|
'amount': V;
|
||||||
|
};
|
||||||
|
'ActionPaidMessagePriceFree': {
|
||||||
|
'peer': V;
|
||||||
|
};
|
||||||
|
'ActionMessageChannelFree': {
|
||||||
|
'peer': V;
|
||||||
|
};
|
||||||
|
'ActionMessageChannelDisabled': {
|
||||||
|
'peer': V;
|
||||||
};
|
};
|
||||||
'ApiMessageActionPaidMessagesRefundedOutgoing': {
|
'ApiMessageActionPaidMessagesRefundedOutgoing': {
|
||||||
'stars': V;
|
'stars': V;
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
import { CHANNEL_ID_LENGTH } from '../../config';
|
import { CHANNEL_ID_BASE } from '../../config';
|
||||||
|
|
||||||
export function isUserId(entityId: string) {
|
export function isUserId(entityId: string) {
|
||||||
return !entityId.startsWith('-');
|
return !entityId.startsWith('-');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isChannelId(entityId: string) {
|
export function isChannelId(entityId: string) {
|
||||||
return entityId.length === CHANNEL_ID_LENGTH && entityId.startsWith('-1');
|
const n = Number(entityId);
|
||||||
|
return n < -CHANNEL_ID_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function toChannelId(mtpId: string) {
|
export function toChannelId(mtpId: string) {
|
||||||
return `-1${mtpId.padStart(CHANNEL_ID_LENGTH - 2, '0')}`;
|
const n = Number(mtpId);
|
||||||
|
return String(-CHANNEL_ID_BASE - n);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCleanPeerId(peerId: string) {
|
export function getCleanPeerId(peerId: string) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user