Forum: Saving the state of the "View as Messages" option (#4091)

This commit is contained in:
Alexander Zinchuk 2023-12-12 12:34:38 +01:00
parent 2edd680802
commit 93aa65cd72
19 changed files with 120 additions and 16 deletions

View File

@ -96,7 +96,7 @@ export function buildApiChatFromDialog(
const { const {
peer, folderId, unreadMark, unreadCount, unreadMentionsCount, unreadReactionsCount, peer, folderId, unreadMark, unreadCount, unreadMentionsCount, unreadReactionsCount,
notifySettings: { silent, muteUntil }, notifySettings: { silent, muteUntil },
readOutboxMaxId, readInboxMaxId, draft, readOutboxMaxId, readInboxMaxId, draft, viewForumAsMessages,
} = dialog; } = dialog;
const isMuted = silent || (typeof muteUntil === 'number' && getServerTime() < muteUntil); const isMuted = silent || (typeof muteUntil === 'number' && getServerTime() < muteUntil);
@ -114,6 +114,7 @@ export function buildApiChatFromDialog(
muteUntil, muteUntil,
...(unreadMark && { hasUnreadMark: true }), ...(unreadMark && { hasUnreadMark: true }),
...(draft instanceof GramJs.DraftMessage && { draftDate: draft.date }), ...(draft instanceof GramJs.DraftMessage && { draftDate: draft.date }),
...(viewForumAsMessages && { isForumAsMessages: true }),
...buildApiChatFieldsFromPeerEntity(peerEntity), ...buildApiChatFieldsFromPeerEntity(peerEntity),
}; };
} }

View File

@ -81,6 +81,7 @@ type FullChatData = {
userStatusesById: { [userId: string]: ApiUserStatus }; userStatusesById: { [userId: string]: ApiUserStatus };
groupCall?: Partial<ApiGroupCall>; groupCall?: Partial<ApiGroupCall>;
membersCount?: number; membersCount?: number;
isForumAsMessages?: true;
}; };
let onUpdate: OnApiUpdate; let onUpdate: OnApiUpdate;
@ -483,6 +484,7 @@ async function getFullChannelInfo(
participantsHidden, participantsHidden,
translationsDisabled, translationsDisabled,
storiesPinnedAvailable, storiesPinnedAvailable,
viewForumAsMessages,
} = result.fullChat; } = result.fullChat;
if (chatPhoto instanceof GramJs.Photo) { if (chatPhoto instanceof GramJs.Photo) {
@ -572,6 +574,7 @@ async function getFullChannelInfo(
connectionState: 'disconnected', connectionState: 'disconnected',
} : undefined, } : undefined,
membersCount: participantsCount, membersCount: participantsCount,
...(viewForumAsMessages && { isForumAsMessages: true }),
}; };
} }
@ -1880,6 +1883,18 @@ export function togglePeerTranslations({
})); }));
} }
export function setViewForumAsMessages({ chat, isEnabled }: { chat: ApiChat; isEnabled: boolean }) {
const { id, accessHash } = chat;
const channel = buildInputEntity(id, accessHash);
return invokeRequest(new GramJs.channels.ToggleViewForumAsMessages({
channel: channel as GramJs.InputChannel,
enabled: Boolean(isEnabled),
}), {
shouldReturnTrue: true,
});
}
function handleUserPrivacyRestrictedUpdates(updates: GramJs.TypeUpdates) { function handleUserPrivacyRestrictedUpdates(updates: GramJs.TypeUpdates) {
if (!(updates instanceof GramJs.Updates) && !(updates instanceof GramJs.UpdatesCombined)) { if (!(updates instanceof GramJs.Updates) && !(updates instanceof GramJs.UpdatesCombined)) {
return undefined; return undefined;

View File

@ -23,7 +23,7 @@ export {
getChatByPhoneNumber, toggleJoinToSend, toggleJoinRequest, fetchTopics, deleteTopic, togglePinnedTopic, getChatByPhoneNumber, toggleJoinToSend, toggleJoinRequest, fetchTopics, deleteTopic, togglePinnedTopic,
editTopic, toggleForum, fetchTopicById, createTopic, toggleParticipantsHidden, checkChatlistInvite, editTopic, toggleForum, fetchTopicById, createTopic, toggleParticipantsHidden, checkChatlistInvite,
joinChatlistInvite, createChalistInvite, editChatlistInvite, deleteChatlistInvite, fetchChatlistInvites, joinChatlistInvite, createChalistInvite, editChatlistInvite, deleteChatlistInvite, fetchChatlistInvites,
fetchLeaveChatlistSuggestions, leaveChatlist, togglePeerTranslations, fetchLeaveChatlistSuggestions, leaveChatlist, togglePeerTranslations, setViewForumAsMessages,
} from './chats'; } from './chats';
export { export {

View File

@ -1131,6 +1131,12 @@ export function updater(update: Update) {
location: update.location, location: update.location,
isUnconfirmed: update.unconfirmed, isUnconfirmed: update.unconfirmed,
}); });
} else if (update instanceof GramJs.UpdateChannelViewForumAsMessages) {
onUpdate({
'@type': 'updateViewForumAsMessages',
chatId: buildApiPeerId(update.channelId, 'channel'),
isEnabled: update.enabled ? true : undefined,
});
} else if (DEBUG) { } else if (DEBUG) {
const params = typeof update === 'object' && 'className' in update ? update.className : update; const params = typeof update === 'object' && 'className' in update ? update.className : update;
log('UNEXPECTED UPDATE', params); log('UNEXPECTED UPDATE', params);

View File

@ -44,6 +44,7 @@ export interface ApiChat {
fakeType?: ApiFakeType; fakeType?: ApiFakeType;
color?: ApiPeerColor; color?: ApiPeerColor;
isForum?: boolean; isForum?: boolean;
isForumAsMessages?: true;
topics?: Record<number, ApiTopic>; topics?: Record<number, ApiTopic>;
listedTopicIds?: number[]; listedTopicIds?: number[];
topicsCount?: number; topicsCount?: number;

View File

@ -609,6 +609,12 @@ export type ApiUpdateTopics = {
chatId: string; chatId: string;
}; };
export type ApiUpdateViewForumAsMessages = {
'@type': 'updateViewForumAsMessages';
chatId: string;
isEnabled?: true;
};
export type ApiUpdateMessageTranslations = { export type ApiUpdateMessageTranslations = {
'@type': 'updateMessageTranslations'; '@type': 'updateMessageTranslations';
chatId: string; chatId: string;
@ -706,7 +712,8 @@ export type ApiUpdate = (
ApiUpdatePinnedTopicsOrder | ApiUpdateTopic | ApiUpdateTopics | ApiUpdateRecentEmojiStatuses | ApiUpdatePinnedTopicsOrder | ApiUpdateTopic | ApiUpdateTopics | ApiUpdateRecentEmojiStatuses |
ApiUpdateRecentReactions | ApiUpdateStory | ApiUpdateReadStories | ApiUpdateDeleteStory | ApiUpdateSentStoryReaction | ApiUpdateRecentReactions | ApiUpdateStory | ApiUpdateReadStories | ApiUpdateDeleteStory | ApiUpdateSentStoryReaction |
ApiRequestReconnectApi | ApiRequestSync | ApiUpdateFetchingDifference | ApiUpdateChannelMessages | ApiRequestReconnectApi | ApiRequestSync | ApiUpdateFetchingDifference | ApiUpdateChannelMessages |
ApiUpdateStealthMode | ApiUpdateAttachMenuBots | ApiUpdateNewAuthorization | ApiUpdateGroupInvitePrivacyForbidden ApiUpdateStealthMode | ApiUpdateAttachMenuBots | ApiUpdateNewAuthorization | ApiUpdateGroupInvitePrivacyForbidden |
ApiUpdateViewForumAsMessages
); );
export type OnApiUpdate = (update: ApiUpdate) => void; export type OnApiUpdate = (update: ApiUpdate) => void;

View File

@ -62,7 +62,7 @@ const ChatForumLastMessage: FC<OwnProps> = ({
handleClick: handleOpenTopicClick, handleClick: handleOpenTopicClick,
handleMouseDown: handleOpenTopicMouseDown, handleMouseDown: handleOpenTopicMouseDown,
} = useFastClick((e: React.MouseEvent<HTMLDivElement>) => { } = useFastClick((e: React.MouseEvent<HTMLDivElement>) => {
if (lastActiveTopic.unreadCount === 0) return; if (lastActiveTopic.unreadCount === 0 || chat.isForumAsMessages) return;
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();

View File

@ -22,6 +22,7 @@ import type {
ApiReaction, ApiReaction,
ApiStealthMode, ApiStealthMode,
ApiSticker, ApiSticker,
ApiTopic,
ApiUser, ApiUser,
ApiVideo, ApiVideo,
} from '../../api/types'; } from '../../api/types';
@ -30,6 +31,7 @@ import type {
MessageListType, TabState, MessageListType, TabState,
} from '../../global/types'; } from '../../global/types';
import type { IAnchorPosition, InlineBotSettings, ISettings } from '../../types'; import type { IAnchorPosition, InlineBotSettings, ISettings } from '../../types';
import { MAIN_THREAD_ID } from '../../api/types';
import { import {
BASE_EMOJI_KEYWORD_LANG, BASE_EMOJI_KEYWORD_LANG,
@ -75,6 +77,7 @@ import {
selectScheduledIds, selectScheduledIds,
selectTabState, selectTabState,
selectTheme, selectTheme,
selectTopicFromMessage,
selectUser, selectUser,
selectUserFullInfo, selectUserFullInfo,
} from '../../global/selectors'; } from '../../global/selectors';
@ -184,6 +187,7 @@ type StateProps =
editingMessage?: ApiMessage; editingMessage?: ApiMessage;
chat?: ApiChat; chat?: ApiChat;
draft?: ApiDraft; draft?: ApiDraft;
replyToTopic?: ApiTopic;
currentMessageList?: MessageList; currentMessageList?: MessageList;
isChatWithBot?: boolean; isChatWithBot?: boolean;
isChatWithSelf?: boolean; isChatWithSelf?: boolean;
@ -282,6 +286,7 @@ const Composer: FC<OwnProps & StateProps> = ({
messageListType, messageListType,
draft, draft,
chat, chat,
replyToTopic,
isForCurrentMessageList, isForCurrentMessageList,
isCurrentUserPremium, isCurrentUserPremium,
canSendVoiceByPrivacy, canSendVoiceByPrivacy,
@ -1292,6 +1297,11 @@ const Composer: FC<OwnProps & StateProps> = ({
|| isCustomSendMenuOpen || Boolean(activeVoiceRecording) || attachments.length > 0 || isInputHasFocus; || isCustomSendMenuOpen || Boolean(activeVoiceRecording) || attachments.length > 0 || isInputHasFocus;
const isReactionSelectorOpen = isComposerHasFocus && !isReactionPickerOpen && isInStoryViewer && !isAttachMenuOpen const isReactionSelectorOpen = isComposerHasFocus && !isReactionPickerOpen && isInStoryViewer && !isAttachMenuOpen
&& !isSymbolMenuOpen; && !isSymbolMenuOpen;
const placeholderForForumAsMessages = chat?.isForum && chat?.isForumAsMessages && threadId === MAIN_THREAD_ID
? (replyToTopic
? lang('Chat.InputPlaceholderReplyInTopic', replyToTopic.title)
: lang('Message.Placeholder.MessageInGeneral'))
: undefined;
useEffect(() => { useEffect(() => {
if (isComposerHasFocus) { if (isComposerHasFocus) {
@ -1680,7 +1690,7 @@ const Composer: FC<OwnProps & StateProps> = ({
activeVoiceRecording && windowWidth <= SCREEN_WIDTH_TO_HIDE_PLACEHOLDER activeVoiceRecording && windowWidth <= SCREEN_WIDTH_TO_HIDE_PLACEHOLDER
? '' ? ''
: (!isComposerBlocked : (!isComposerBlocked
? (botKeyboardPlaceholder || inputPlaceholder || lang('Message')) ? (botKeyboardPlaceholder || inputPlaceholder || lang(placeholderForForumAsMessages || 'Message'))
: lang('Chat.PlaceholderTextNotAllowed')) : lang('Chat.PlaceholderTextNotAllowed'))
} }
timedPlaceholderDate={timedPlaceholderDate} timedPlaceholderDate={timedPlaceholderDate}
@ -1932,13 +1942,20 @@ export default memo(withGlobal<OwnProps>(
const story = storyId && selectPeerStory(global, chatId, storyId); const story = storyId && selectPeerStory(global, chatId, storyId);
const sentStoryReaction = story && 'sentReaction' in story ? story.sentReaction : undefined; const sentStoryReaction = story && 'sentReaction' in story ? story.sentReaction : undefined;
const draft = selectDraft(global, chatId, threadId);
const replyToMessage = draft?.replyInfo
? selectChatMessage(global, chatId, draft.replyInfo.replyToMsgId)
: undefined;
const replyToTopic = chat?.isForum && chat.isForumAsMessages && threadId === MAIN_THREAD_ID && replyToMessage
? selectTopicFromMessage(global, replyToMessage)
: undefined;
return { return {
availableReactions: type === 'story' ? global.availableReactions : undefined, availableReactions: type === 'story' ? global.availableReactions : undefined,
topReactions: type === 'story' ? global.topReactions : undefined, topReactions: type === 'story' ? global.topReactions : undefined,
isOnActiveTab: !tabState.isBlurred, isOnActiveTab: !tabState.isBlurred,
editingMessage: selectEditingMessage(global, chatId, threadId, messageListType), editingMessage: selectEditingMessage(global, chatId, threadId, messageListType),
draft: selectDraft(global, chatId, threadId), draft,
chat, chat,
isChatWithBot, isChatWithBot,
isChatWithSelf, isChatWithSelf,
@ -1996,6 +2013,7 @@ export default memo(withGlobal<OwnProps>(
shouldCollectDebugLogs: global.settings.byKey.shouldCollectDebugLogs, shouldCollectDebugLogs: global.settings.byKey.shouldCollectDebugLogs,
sentStoryReaction, sentStoryReaction,
stealthMode: global.stories.stealthMode, stealthMode: global.stories.stealthMode,
replyToTopic,
}; };
}, },
)(Composer)); )(Composer));

View File

@ -173,12 +173,13 @@ const EmbeddedMessage: FC<OwnProps> = ({
} }
const isChatSender = senderChat?.id === sender?.id; const isChatSender = senderChat?.id === sender?.id;
const isReplyToQuote = isInComposer && Boolean(replyInfo && 'quoteText' in replyInfo && replyInfo?.quoteText);
return ( return (
<> <>
{!isChatSender && ( {!isChatSender && (
<span className="embedded-sender"> <span className="embedded-sender">
{renderText(isInComposer ? lang('ReplyToQuote', senderTitle) : senderTitle)} {renderText(isReplyToQuote ? lang('ReplyToQuote', senderTitle) : senderTitle)}
</span> </span>
)} )}
{icon && <Icon name={icon} className="embedded-chat-icon" />} {icon && <Icon name={icon} className="embedded-chat-icon" />}

View File

@ -147,7 +147,7 @@ const Chat: FC<OwnProps & StateProps> = ({
const [shouldRenderChatFolderModal, markRenderChatFolderModal, unmarkRenderChatFolderModal] = useFlag(); const [shouldRenderChatFolderModal, markRenderChatFolderModal, unmarkRenderChatFolderModal] = useFlag();
const [shouldRenderReportModal, markRenderReportModal, unmarkRenderReportModal] = useFlag(); const [shouldRenderReportModal, markRenderReportModal, unmarkRenderReportModal] = useFlag();
const { lastMessage, isForum } = chat || {}; const { lastMessage, isForum, isForumAsMessages } = chat || {};
const { renderSubtitle, ref } = useChatListEntry({ const { renderSubtitle, ref } = useChatListEntry({
chat, chat,
@ -169,17 +169,23 @@ const Chat: FC<OwnProps & StateProps> = ({
const getIsForumPanelClosed = useSelectorSignal(selectIsForumPanelClosed); const getIsForumPanelClosed = useSelectorSignal(selectIsForumPanelClosed);
const handleClick = useLastCallback(() => { const handleClick = useLastCallback(() => {
const noForumTopicPanel = isMobile && isForumAsMessages;
if (isForum) { if (isForum) {
if (isForumPanelOpen) { if (isForumPanelOpen) {
closeForumPanel(undefined, { forceOnHeavyAnimation: true }); closeForumPanel(undefined, { forceOnHeavyAnimation: true });
} else {
openForumPanel({ chatId }, { forceOnHeavyAnimation: true });
}
return; return;
} else {
if (!noForumTopicPanel) {
openForumPanel({ chatId }, { forceOnHeavyAnimation: true });
}
if (!isForumAsMessages) return;
}
} }
openChat({ id: chatId, shouldReplaceHistory: true }, { forceOnHeavyAnimation: true }); openChat({ id: chatId, noForumTopicPanel, shouldReplaceHistory: true }, { forceOnHeavyAnimation: true });
if (isSelected && canScrollDown) { if (isSelected && canScrollDown) {
focusLastMessage(); focusLastMessage();

View File

@ -92,7 +92,12 @@ const Topic: FC<OwnProps & StateProps> = ({
draft, draft,
wasTopicOpened, wasTopicOpened,
}) => { }) => {
const { openThread, deleteTopic, focusLastMessage } = getActions(); const {
openThread,
deleteTopic,
focusLastMessage,
setViewForumAsMessages,
} = getActions();
const lang = useLang(); const lang = useLang();
@ -141,6 +146,7 @@ const Topic: FC<OwnProps & StateProps> = ({
const handleOpenTopic = useLastCallback(() => { const handleOpenTopic = useLastCallback(() => {
openThread({ chatId, threadId: topic.id, shouldReplaceHistory: true }); openThread({ chatId, threadId: topic.id, shouldReplaceHistory: true });
setViewForumAsMessages({ chatId, isEnabled: false });
if (canScrollDown) { if (canScrollDown) {
focusLastMessage(); focusLastMessage();

View File

@ -130,6 +130,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
openChatLanguageModal, openChatLanguageModal,
setSettingOption, setSettingOption,
unblockUser, unblockUser,
setViewForumAsMessages,
} = getActions(); } = getActions();
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
const menuButtonRef = useRef<HTMLButtonElement>(null); const menuButtonRef = useRef<HTMLButtonElement>(null);
@ -209,6 +210,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
const handleAsMessagesClick = useLastCallback(() => { const handleAsMessagesClick = useLastCallback(() => {
openChat({ id: chatId }); openChat({ id: chatId });
setViewForumAsMessages({ chatId, isEnabled: true });
}); });
function handleRequestCall() { function handleRequestCall() {

View File

@ -104,6 +104,7 @@ type StateProps = {
isMuted?: boolean; isMuted?: boolean;
isTopic?: boolean; isTopic?: boolean;
isForum?: boolean; isForum?: boolean;
isForumAsMessages?: true;
canAddContact?: boolean; canAddContact?: boolean;
canReportChat?: boolean; canReportChat?: boolean;
canDeleteChat?: boolean; canDeleteChat?: boolean;
@ -133,6 +134,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
withForumActions, withForumActions,
isTopic, isTopic,
isForum, isForum,
isForumAsMessages,
isChatInfoShown, isChatInfoShown,
canStartBot, canStartBot,
canSubscribe, canSubscribe,
@ -189,6 +191,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
togglePeerTranslations, togglePeerTranslations,
blockUser, blockUser,
unblockUser, unblockUser,
setViewForumAsMessages,
} = getActions(); } = getActions();
const { isMobile } = useAppLayout(); const { isMobile } = useAppLayout();
@ -280,6 +283,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
const handleViewAsTopicsClick = useLastCallback(() => { const handleViewAsTopicsClick = useLastCallback(() => {
openChat({ id: undefined }); openChat({ id: undefined });
setViewForumAsMessages({ chatId, isEnabled: false });
closeMenu(); closeMenu();
}); });
@ -469,7 +473,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
<div className="right-badge">{pendingJoinRequests}</div> <div className="right-badge">{pendingJoinRequests}</div>
</MenuItem> </MenuItem>
)} )}
{withForumActions && !isTopic && ( {withForumActions && !isTopic && !isForumAsMessages && (
<MenuItem <MenuItem
icon="message" icon="message"
onClick={handleOpenAsMessages} onClick={handleOpenAsMessages}
@ -696,6 +700,7 @@ export default memo(withGlobal<OwnProps>(
isPrivate, isPrivate,
isTopic: chat?.isForum && !isMainThread, isTopic: chat?.isForum && !isMainThread,
isForum: chat?.isForum, isForum: chat?.isForum,
isForumAsMessages: chat?.isForumAsMessages,
canAddContact, canAddContact,
canReportChat, canReportChat,
canDeleteChat: getCanDeleteChat(chat), canDeleteChat: getCanDeleteChat(chat),

View File

@ -327,6 +327,7 @@ export default memo(withGlobal<OwnProps>(
const draft = selectDraft(global, chatId, threadId); const draft = selectDraft(global, chatId, threadId);
const replyInfo = draft?.replyInfo; const replyInfo = draft?.replyInfo;
let message: ApiMessage | undefined; let message: ApiMessage | undefined;
if (replyInfo && !shouldForceShowEditing) { if (replyInfo && !shouldForceShowEditing) {
message = selectChatMessage(global, replyInfo.replyToPeerId || chatId, replyInfo.replyToMsgId); message = selectChatMessage(global, replyInfo.replyToPeerId || chatId, replyInfo.replyToMsgId);

View File

@ -2503,6 +2503,20 @@ addActionHandler('togglePeerTranslations', async (global, actions, payload): Pro
setGlobal(global); setGlobal(global);
}); });
addActionHandler('setViewForumAsMessages', (global, actions, payload): ActionReturnType => {
const { chatId, isEnabled } = payload;
const chat = selectChat(global, chatId);
if (!chat?.isForum || chat.isForumAsMessages === isEnabled) {
return;
}
global = updateChat(global, chatId, { isForumAsMessages: isEnabled || undefined });
setGlobal(global);
void callApi('setViewForumAsMessages', { chat, isEnabled });
});
async function loadChats( async function loadChats(
listType: 'active' | 'archived', listType: 'active' | 'archived',
offsetId?: string, offsetId?: string,
@ -2638,7 +2652,7 @@ export async function loadFullChat<T extends GlobalState>(
} }
const { const {
users, userStatusesById, fullInfo, groupCall, membersCount, users, userStatusesById, fullInfo, groupCall, membersCount, isForumAsMessages,
} = result; } = result;
global = getGlobal(); global = getGlobal();
@ -2664,6 +2678,9 @@ export async function loadFullChat<T extends GlobalState>(
if (membersCount !== undefined) { if (membersCount !== undefined) {
global = updateChat(global, chat.id, { membersCount }); global = updateChat(global, chat.id, { membersCount });
} }
if (chat.isForum) {
global = updateChat(global, chat.id, { isForumAsMessages });
}
global = replaceChatFullInfo(global, chat.id, fullInfo); global = replaceChatFullInfo(global, chat.id, fullInfo);
setGlobal(global); setGlobal(global);

View File

@ -469,6 +469,18 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
return undefined; return undefined;
} }
case 'updateViewForumAsMessages': {
const { chatId, isEnabled } = update;
const chat = selectChat(global, chatId);
if (!chat?.isForum) return undefined;
global = updateChat(global, chatId, {
isForumAsMessages: isEnabled,
});
setGlobal(global);
}
} }
return undefined; return undefined;

View File

@ -2819,6 +2819,10 @@ export interface ActionPayloads {
isMuted?: boolean; isMuted?: boolean;
muteUntil?: number; muteUntil?: number;
}; };
setViewForumAsMessages: {
chatId: string;
isEnabled: boolean;
};
openCreateTopicPanel: { openCreateTopicPanel: {
chatId: string; chatId: string;

View File

@ -1442,6 +1442,7 @@ channels.updatePinnedForumTopic#6c2d9026 channel:InputChannel topic_id:int pinne
channels.deleteTopicHistory#34435f2d channel:InputChannel top_msg_id:int = messages.AffectedHistory; channels.deleteTopicHistory#34435f2d channel:InputChannel top_msg_id:int = messages.AffectedHistory;
channels.toggleParticipantsHidden#6a6e7854 channel:InputChannel enabled:Bool = Updates; channels.toggleParticipantsHidden#6a6e7854 channel:InputChannel enabled:Bool = Updates;
channels.clickSponsoredMessage#18afbc93 channel:InputChannel random_id:bytes = Bool; channels.clickSponsoredMessage#18afbc93 channel:InputChannel random_id:bytes = Bool;
channels.toggleViewForumAsMessages#9738bb15 channel:InputChannel enabled:Bool = Updates;
bots.canSendMessage#1359f4e6 bot:InputUser = Bool; bots.canSendMessage#1359f4e6 bot:InputUser = Bool;
bots.allowSendMessage#f132e3ef bot:InputUser = Updates; bots.allowSendMessage#f132e3ef bot:InputUser = Updates;
bots.invokeWebViewCustomMethod#87fc5e7 bot:InputUser custom_method:string params:DataJSON = DataJSON; bots.invokeWebViewCustomMethod#87fc5e7 bot:InputUser custom_method:string params:DataJSON = DataJSON;

View File

@ -289,6 +289,7 @@
"channels.deleteTopicHistory", "channels.deleteTopicHistory",
"channels.toggleParticipantsHidden", "channels.toggleParticipantsHidden",
"channels.clickSponsoredMessage", "channels.clickSponsoredMessage",
"channels.toggleViewForumAsMessages",
"photos.uploadContactProfilePhoto", "photos.uploadContactProfilePhoto",
"messages.getMessagesViews", "messages.getMessagesViews",
"chatlists.exportChatlistInvite", "chatlists.exportChatlistInvite",