Bots: Better forum view handling (#6705)
This commit is contained in:
parent
48b722939b
commit
fc1883f1cc
@ -112,7 +112,7 @@ export function buildApiUser(mtpUser: GramJs.TypeUser): ApiUser | undefined {
|
|||||||
const {
|
const {
|
||||||
id, firstName, lastName, fake, scam, support, closeFriend, storiesUnavailable,
|
id, firstName, lastName, fake, scam, support, closeFriend, storiesUnavailable,
|
||||||
bot, botActiveUsers, botVerificationIcon, botInlinePlaceholder, botAttachMenu, botCanEdit,
|
bot, botActiveUsers, botVerificationIcon, botInlinePlaceholder, botAttachMenu, botCanEdit,
|
||||||
sendPaidMessagesStars, profileColor, botForumView,
|
sendPaidMessagesStars, profileColor, botForumView, botForumCanManageTopics,
|
||||||
} = mtpUser;
|
} = mtpUser;
|
||||||
const storiesMaxId = mtpUser.storiesMaxId?.maxId;
|
const storiesMaxId = mtpUser.storiesMaxId?.maxId;
|
||||||
const hasVideoAvatar = mtpUser.photo instanceof GramJs.UserProfilePhoto ? Boolean(mtpUser.photo.hasVideo) : undefined;
|
const hasVideoAvatar = mtpUser.photo instanceof GramJs.UserProfilePhoto ? Boolean(mtpUser.photo.hasVideo) : undefined;
|
||||||
@ -157,6 +157,7 @@ export function buildApiUser(mtpUser: GramJs.TypeUser): ApiUser | undefined {
|
|||||||
profileColor: profileColor && buildApiPeerColor(profileColor),
|
profileColor: profileColor && buildApiPeerColor(profileColor),
|
||||||
paidMessagesStars: toJSNumber(sendPaidMessagesStars),
|
paidMessagesStars: toJSNumber(sendPaidMessagesStars),
|
||||||
isBotForum: botForumView,
|
isBotForum: botForumView,
|
||||||
|
canManageBotForumTopics: botForumCanManageTopics,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,7 @@ export interface ApiUser {
|
|||||||
botVerificationIconId?: string;
|
botVerificationIconId?: string;
|
||||||
paidMessagesStars?: number;
|
paidMessagesStars?: number;
|
||||||
isBotForum?: boolean;
|
isBotForum?: boolean;
|
||||||
|
canManageBotForumTopics?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApiUserFullInfo {
|
export interface ApiUserFullInfo {
|
||||||
|
|||||||
@ -1374,6 +1374,7 @@
|
|||||||
"ComposerPlaceholderBroadcastSilent" = "Silent Broadcast";
|
"ComposerPlaceholderBroadcastSilent" = "Silent Broadcast";
|
||||||
"ComposerPlaceholderTopic" = "Message in {topic}";
|
"ComposerPlaceholderTopic" = "Message in {topic}";
|
||||||
"ComposerPlaceholderTopicGeneral" = "Message in General";
|
"ComposerPlaceholderTopicGeneral" = "Message in General";
|
||||||
|
"ComposerPlaceholderBotTopicGeneral" = "Off-thread message";
|
||||||
"ComposerStoryPlaceholderLocked" = "Replies restricted";
|
"ComposerStoryPlaceholderLocked" = "Replies restricted";
|
||||||
"ComposerPlaceholderNoText" = "Text not allowed";
|
"ComposerPlaceholderNoText" = "Text not allowed";
|
||||||
"AriaComposerCancelVoice" = "Cancel voice recording";
|
"AriaComposerCancelVoice" = "Cancel voice recording";
|
||||||
|
|||||||
@ -222,96 +222,96 @@ type OwnProps = {
|
|||||||
onBlur?: NoneToVoidFunction;
|
onBlur?: NoneToVoidFunction;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps =
|
type StateProps = {
|
||||||
{
|
isOnActiveTab: boolean;
|
||||||
isOnActiveTab: boolean;
|
editingMessage?: ApiMessage;
|
||||||
editingMessage?: ApiMessage;
|
chat?: ApiChat;
|
||||||
chat?: ApiChat;
|
user?: ApiUser;
|
||||||
chatFullInfo?: ApiChatFullInfo;
|
chatFullInfo?: ApiChatFullInfo;
|
||||||
draft?: ApiDraft;
|
draft?: ApiDraft;
|
||||||
replyToTopic?: ApiTopic;
|
replyToTopic?: ApiTopic;
|
||||||
currentMessageList?: MessageList;
|
currentMessageList?: MessageList;
|
||||||
isChatWithBot?: boolean;
|
isChatWithBot?: boolean;
|
||||||
isChatWithSelf?: boolean;
|
isChatWithSelf?: boolean;
|
||||||
isChannel?: boolean;
|
isChannel?: boolean;
|
||||||
isForCurrentMessageList: boolean;
|
isForCurrentMessageList: boolean;
|
||||||
isRightColumnShown?: boolean;
|
isRightColumnShown?: boolean;
|
||||||
isSelectModeActive?: boolean;
|
isSelectModeActive?: boolean;
|
||||||
isReactionPickerOpen?: boolean;
|
isReactionPickerOpen?: boolean;
|
||||||
shouldDisplayGiftsButton?: boolean;
|
shouldDisplayGiftsButton?: boolean;
|
||||||
isForwarding?: boolean;
|
isForwarding?: boolean;
|
||||||
isReplying?: boolean;
|
isReplying?: boolean;
|
||||||
hasSuggestedPost?: boolean;
|
hasSuggestedPost?: boolean;
|
||||||
forwardedMessagesCount?: number;
|
forwardedMessagesCount?: number;
|
||||||
pollModal: TabState['pollModal'];
|
pollModal: TabState['pollModal'];
|
||||||
todoListModal: TabState['todoListModal'];
|
todoListModal: TabState['todoListModal'];
|
||||||
botKeyboardMessageId?: number;
|
botKeyboardMessageId?: number;
|
||||||
botKeyboardPlaceholder?: string;
|
botKeyboardPlaceholder?: string;
|
||||||
withScheduledButton?: boolean;
|
withScheduledButton?: boolean;
|
||||||
isInScheduledList?: boolean;
|
isInScheduledList?: boolean;
|
||||||
canScheduleUntilOnline?: boolean;
|
canScheduleUntilOnline?: boolean;
|
||||||
stickersForEmoji?: ApiSticker[];
|
stickersForEmoji?: ApiSticker[];
|
||||||
customEmojiForEmoji?: ApiSticker[];
|
customEmojiForEmoji?: ApiSticker[];
|
||||||
currentUserId?: string;
|
currentUserId?: string;
|
||||||
currentUser?: ApiUser;
|
currentUser?: ApiUser;
|
||||||
recentEmojis: string[];
|
recentEmojis: string[];
|
||||||
contentToBeScheduled?: TabState['contentToBeScheduled'];
|
contentToBeScheduled?: TabState['contentToBeScheduled'];
|
||||||
shouldSuggestStickers?: boolean;
|
shouldSuggestStickers?: boolean;
|
||||||
shouldSuggestCustomEmoji?: boolean;
|
shouldSuggestCustomEmoji?: boolean;
|
||||||
baseEmojiKeywords?: Record<string, string[]>;
|
baseEmojiKeywords?: Record<string, string[]>;
|
||||||
emojiKeywords?: Record<string, string[]>;
|
emojiKeywords?: Record<string, string[]>;
|
||||||
topInlineBotIds?: string[];
|
topInlineBotIds?: string[];
|
||||||
isInlineBotLoading: boolean;
|
isInlineBotLoading: boolean;
|
||||||
inlineBots?: Record<string, false | InlineBotSettings>;
|
inlineBots?: Record<string, false | InlineBotSettings>;
|
||||||
botCommands?: ApiBotCommand[] | false;
|
botCommands?: ApiBotCommand[] | false;
|
||||||
botMenuButton?: ApiBotMenuButton;
|
botMenuButton?: ApiBotMenuButton;
|
||||||
sendAsPeer?: ApiPeer;
|
sendAsPeer?: ApiPeer;
|
||||||
sendAsId?: string;
|
sendAsId?: string;
|
||||||
editingDraft?: ApiFormattedText;
|
editingDraft?: ApiFormattedText;
|
||||||
requestedDraft?: ApiFormattedText;
|
requestedDraft?: ApiFormattedText;
|
||||||
requestedDraftFiles?: File[];
|
requestedDraftFiles?: File[];
|
||||||
attachBots: GlobalState['attachMenu']['bots'];
|
attachBots: GlobalState['attachMenu']['bots'];
|
||||||
attachMenuPeerType?: ApiAttachMenuPeerType;
|
attachMenuPeerType?: ApiAttachMenuPeerType;
|
||||||
theme: ThemeKey;
|
theme: ThemeKey;
|
||||||
fileSizeLimit: number;
|
fileSizeLimit: number;
|
||||||
captionLimit: number;
|
captionLimit: number;
|
||||||
isCurrentUserPremium?: boolean;
|
isCurrentUserPremium?: boolean;
|
||||||
canSendVoiceByPrivacy?: boolean;
|
canSendVoiceByPrivacy?: boolean;
|
||||||
attachmentSettings: GlobalState['attachmentSettings'];
|
attachmentSettings: GlobalState['attachmentSettings'];
|
||||||
slowMode?: ApiChatFullInfo['slowMode'];
|
slowMode?: ApiChatFullInfo['slowMode'];
|
||||||
shouldUpdateStickerSetOrder?: boolean;
|
shouldUpdateStickerSetOrder?: boolean;
|
||||||
availableReactions?: ApiAvailableReaction[];
|
availableReactions?: ApiAvailableReaction[];
|
||||||
topReactions?: ApiReaction[];
|
topReactions?: ApiReaction[];
|
||||||
canPlayAnimatedEmojis?: boolean;
|
canPlayAnimatedEmojis?: boolean;
|
||||||
canBuyPremium?: boolean;
|
canBuyPremium?: boolean;
|
||||||
shouldCollectDebugLogs?: boolean;
|
shouldCollectDebugLogs?: boolean;
|
||||||
sentStoryReaction?: ApiReaction;
|
sentStoryReaction?: ApiReaction;
|
||||||
stealthMode?: ApiStealthMode;
|
stealthMode?: ApiStealthMode;
|
||||||
canSendOneTimeMedia?: boolean;
|
canSendOneTimeMedia?: boolean;
|
||||||
quickReplyMessages?: Record<number, ApiMessage>;
|
quickReplyMessages?: Record<number, ApiMessage>;
|
||||||
quickReplies?: Record<number, ApiQuickReply>;
|
quickReplies?: Record<number, ApiQuickReply>;
|
||||||
canSendQuickReplies?: boolean;
|
canSendQuickReplies?: boolean;
|
||||||
webPagePreview?: ApiWebPage;
|
webPagePreview?: ApiWebPage;
|
||||||
noWebPage?: boolean;
|
noWebPage?: boolean;
|
||||||
isContactRequirePremium?: boolean;
|
isContactRequirePremium?: boolean;
|
||||||
paidMessagesStars?: number;
|
paidMessagesStars?: number;
|
||||||
effect?: ApiAvailableEffect;
|
effect?: ApiAvailableEffect;
|
||||||
effectReactions?: ApiReaction[];
|
effectReactions?: ApiReaction[];
|
||||||
areEffectsSupported?: boolean;
|
areEffectsSupported?: boolean;
|
||||||
canPlayEffect?: boolean;
|
canPlayEffect?: boolean;
|
||||||
shouldPlayEffect?: boolean;
|
shouldPlayEffect?: boolean;
|
||||||
maxMessageLength: number;
|
maxMessageLength: number;
|
||||||
shouldPaidMessageAutoApprove?: boolean;
|
shouldPaidMessageAutoApprove?: boolean;
|
||||||
isSilentPosting?: boolean;
|
isSilentPosting?: boolean;
|
||||||
isPaymentMessageConfirmDialogOpen: boolean;
|
isPaymentMessageConfirmDialogOpen: boolean;
|
||||||
starsBalance: number;
|
starsBalance: number;
|
||||||
isStarsBalanceModalOpen: boolean;
|
isStarsBalanceModalOpen: boolean;
|
||||||
disallowedGifts?: ApiDisallowedGifts;
|
disallowedGifts?: ApiDisallowedGifts;
|
||||||
isAccountFrozen?: boolean;
|
isAccountFrozen?: boolean;
|
||||||
isAppConfigLoaded?: boolean;
|
isAppConfigLoaded?: boolean;
|
||||||
insertingPeerIdMention?: string;
|
insertingPeerIdMention?: string;
|
||||||
pollMaxAnswers?: number;
|
pollMaxAnswers?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MainButtonState {
|
enum MainButtonState {
|
||||||
Send = 'send',
|
Send = 'send',
|
||||||
@ -352,6 +352,7 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
draft,
|
draft,
|
||||||
chat,
|
chat,
|
||||||
chatFullInfo,
|
chatFullInfo,
|
||||||
|
user,
|
||||||
replyToTopic,
|
replyToTopic,
|
||||||
isForCurrentMessageList,
|
isForCurrentMessageList,
|
||||||
isCurrentUserPremium,
|
isCurrentUserPremium,
|
||||||
@ -1758,6 +1759,10 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
return lang('ComposerPlaceholderAnonymous');
|
return lang('ComposerPlaceholderAnonymous');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (chat?.isBotForum && !user?.canManageBotForumTopics && threadId === MAIN_THREAD_ID) {
|
||||||
|
return lang('ComposerPlaceholderBotTopicGeneral');
|
||||||
|
}
|
||||||
|
|
||||||
if (chat?.isForum && !chat.isBotForum && chat.isForumAsMessages && threadId === MAIN_THREAD_ID) {
|
if (chat?.isForum && !chat.isBotForum && chat.isForumAsMessages && threadId === MAIN_THREAD_ID) {
|
||||||
return replyToTopic
|
return replyToTopic
|
||||||
? lang('ComposerPlaceholderTopic', { topic: replyToTopic.title })
|
? lang('ComposerPlaceholderTopic', { topic: replyToTopic.title })
|
||||||
@ -1775,7 +1780,7 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
}, [
|
}, [
|
||||||
activeVoiceRecording, botKeyboardPlaceholder, chat, inputPlaceholder, isChannel, isComposerBlocked,
|
activeVoiceRecording, botKeyboardPlaceholder, chat, inputPlaceholder, isChannel, isComposerBlocked,
|
||||||
isInStoryViewer, isSilentPosting, lang, replyToTopic, isReplying, threadId, windowWidth, paidMessagesStars,
|
isInStoryViewer, isSilentPosting, lang, replyToTopic, isReplying, threadId, windowWidth, paidMessagesStars,
|
||||||
hasSuggestedPost, slowModePlaceholder, stealthMode?.activeUntil,
|
hasSuggestedPost, slowModePlaceholder, stealthMode?.activeUntil, user?.canManageBotForumTopics,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -2635,6 +2640,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
editingMessage: selectEditingMessage(global, chatId, threadId, messageListType),
|
editingMessage: selectEditingMessage(global, chatId, threadId, messageListType),
|
||||||
draft,
|
draft,
|
||||||
chat,
|
chat,
|
||||||
|
user,
|
||||||
isChatWithBot,
|
isChatWithBot,
|
||||||
isChatWithSelf,
|
isChatWithSelf,
|
||||||
isForCurrentMessageList,
|
isForCurrentMessageList,
|
||||||
|
|||||||
@ -204,6 +204,8 @@ const Chat: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
const { isForum, isForumAsMessages, isMonoforum } = chat || {};
|
const { isForum, isForumAsMessages, isMonoforum } = chat || {};
|
||||||
|
|
||||||
|
const shouldForceNonForumView = chat?.isBotForum && listedTopicIds && !listedTopicIds.length;
|
||||||
|
|
||||||
useEnsureMessage(isSavedDialog ? currentUserId : chatId, lastMessageId, lastMessage);
|
useEnsureMessage(isSavedDialog ? currentUserId : chatId, lastMessageId, lastMessage);
|
||||||
|
|
||||||
const tagFolderIds = useMemo(() => {
|
const tagFolderIds = useMemo(() => {
|
||||||
@ -244,6 +246,7 @@ const Chat: FC<OwnProps & StateProps> = ({
|
|||||||
onReorderAnimationEnd,
|
onReorderAnimationEnd,
|
||||||
topicIds: listedTopicIds,
|
topicIds: listedTopicIds,
|
||||||
hasTags: shouldRenderTags,
|
hasTags: shouldRenderTags,
|
||||||
|
shouldForceNonForumView,
|
||||||
});
|
});
|
||||||
|
|
||||||
const getIsForumPanelClosed = useSelectorSignal(selectIsForumPanelClosed);
|
const getIsForumPanelClosed = useSelectorSignal(selectIsForumPanelClosed);
|
||||||
@ -255,7 +258,7 @@ const Chat: FC<OwnProps & StateProps> = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const noForumTopicPanel = isMobile && isForumAsMessages;
|
const noForumTopicPanel = (isMobile && isForumAsMessages) || shouldForceNonForumView;
|
||||||
|
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
setShouldCloseRightColumn({ value: true });
|
setShouldCloseRightColumn({ value: true });
|
||||||
@ -288,7 +291,7 @@ const Chat: FC<OwnProps & StateProps> = ({
|
|||||||
openForumPanel({ chatId }, { forceOnHeavyAnimation: true });
|
openForumPanel({ chatId }, { forceOnHeavyAnimation: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isForumAsMessages) return;
|
if (!isForumAsMessages && !shouldForceNonForumView) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +400,7 @@ const Chat: FC<OwnProps & StateProps> = ({
|
|||||||
const chatClassName = buildClassName(
|
const chatClassName = buildClassName(
|
||||||
'Chat chat-item-clickable',
|
'Chat chat-item-clickable',
|
||||||
isUserId(chatId) ? 'private' : 'group',
|
isUserId(chatId) ? 'private' : 'group',
|
||||||
isForum && 'forum',
|
isForum && !shouldForceNonForumView && 'forum',
|
||||||
isSelected && 'selected',
|
isSelected && 'selected',
|
||||||
isSelectedForum && 'selected-forum',
|
isSelectedForum && 'selected-forum',
|
||||||
isPreview && 'standalone',
|
isPreview && 'standalone',
|
||||||
|
|||||||
@ -53,6 +53,7 @@ export default function useChatListEntry({
|
|||||||
isSavedDialog,
|
isSavedDialog,
|
||||||
isPreview,
|
isPreview,
|
||||||
hasTags,
|
hasTags,
|
||||||
|
shouldForceNonForumView,
|
||||||
onReorderAnimationEnd,
|
onReorderAnimationEnd,
|
||||||
}: {
|
}: {
|
||||||
chat?: ApiChat;
|
chat?: ApiChat;
|
||||||
@ -74,6 +75,7 @@ export default function useChatListEntry({
|
|||||||
orderDiff: number;
|
orderDiff: number;
|
||||||
shiftDiff: number;
|
shiftDiff: number;
|
||||||
withInterfaceAnimations?: boolean;
|
withInterfaceAnimations?: boolean;
|
||||||
|
shouldForceNonForumView?: boolean;
|
||||||
onReorderAnimationEnd?: NoneToVoidFunction;
|
onReorderAnimationEnd?: NoneToVoidFunction;
|
||||||
}) {
|
}) {
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
@ -151,7 +153,8 @@ export default function useChatListEntry({
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
function renderSubtitle() {
|
function renderSubtitle() {
|
||||||
if (chat?.isForum && !isTopic) {
|
const shouldRenderAsForum = chat?.isForum && !isTopic && !shouldForceNonForumView;
|
||||||
|
if (shouldRenderAsForum) {
|
||||||
return (
|
return (
|
||||||
<ChatForumLastMessage
|
<ChatForumLastMessage
|
||||||
chat={chat}
|
chat={chat}
|
||||||
|
|||||||
@ -114,6 +114,7 @@ type StateProps = {
|
|||||||
isMuted?: boolean;
|
isMuted?: boolean;
|
||||||
isTopic?: boolean;
|
isTopic?: boolean;
|
||||||
isForum?: boolean;
|
isForum?: boolean;
|
||||||
|
isBotForum?: boolean;
|
||||||
isForumAsMessages?: true;
|
isForumAsMessages?: true;
|
||||||
canAddContact?: boolean;
|
canAddContact?: boolean;
|
||||||
canDeleteChat?: boolean;
|
canDeleteChat?: boolean;
|
||||||
@ -148,6 +149,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
|||||||
withForumActions,
|
withForumActions,
|
||||||
isTopic,
|
isTopic,
|
||||||
isForum,
|
isForum,
|
||||||
|
isBotForum,
|
||||||
isForumAsMessages,
|
isForumAsMessages,
|
||||||
isChatInfoShown,
|
isChatInfoShown,
|
||||||
canStartBot,
|
canStartBot,
|
||||||
@ -627,7 +629,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
|||||||
{oldLang('lng_forum_topic_edit')}
|
{oldLang('lng_forum_topic_edit')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
{isMobile && !withForumActions && isForum && !isTopic && (
|
{isMobile && !withForumActions && isForum && !isBotForum && !isTopic && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="forums"
|
icon="forums"
|
||||||
onClick={handleViewAsTopicsClick}
|
onClick={handleViewAsTopicsClick}
|
||||||
@ -644,7 +646,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
|||||||
<div className="right-badge">{pendingJoinRequests}</div>
|
<div className="right-badge">{pendingJoinRequests}</div>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
{withForumActions && !isTopic && !isForumAsMessages && (
|
{withForumActions && !isTopic && !isBotForum && !isForumAsMessages && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="message"
|
icon="message"
|
||||||
onClick={handleOpenAsMessages}
|
onClick={handleOpenAsMessages}
|
||||||
@ -883,6 +885,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
isPrivate,
|
isPrivate,
|
||||||
isTopic: chat?.isForum && !isMainThread,
|
isTopic: chat?.isForum && !isMainThread,
|
||||||
isForum: chat?.isForum,
|
isForum: chat?.isForum,
|
||||||
|
isBotForum: chat?.isBotForum,
|
||||||
isForumAsMessages: chat?.isForumAsMessages,
|
isForumAsMessages: chat?.isForumAsMessages,
|
||||||
canAddContact,
|
canAddContact,
|
||||||
canDeleteChat: getCanDeleteChat(chat),
|
canDeleteChat: getCanDeleteChat(chat),
|
||||||
|
|||||||
@ -45,6 +45,7 @@ import {
|
|||||||
selectTabState,
|
selectTabState,
|
||||||
selectTopic,
|
selectTopic,
|
||||||
selectTranslationLanguage,
|
selectTranslationLanguage,
|
||||||
|
selectUser,
|
||||||
selectUserFullInfo,
|
selectUserFullInfo,
|
||||||
} from '../../global/selectors';
|
} from '../../global/selectors';
|
||||||
import { selectIsChatRestricted } from '../../global/selectors/chats';
|
import { selectIsChatRestricted } from '../../global/selectors/chats';
|
||||||
@ -149,7 +150,7 @@ type StateProps = {
|
|||||||
translationLanguage?: string;
|
translationLanguage?: string;
|
||||||
shouldAutoTranslate?: boolean;
|
shouldAutoTranslate?: boolean;
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
isBotForum?: boolean;
|
canManageBotForumTopics?: boolean;
|
||||||
shouldScrollToBottom?: boolean;
|
shouldScrollToBottom?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -199,7 +200,7 @@ const MessageList = ({
|
|||||||
canPost,
|
canPost,
|
||||||
isSynced,
|
isSynced,
|
||||||
isActive,
|
isActive,
|
||||||
isBotForum,
|
canManageBotForumTopics,
|
||||||
shouldScrollToBottom,
|
shouldScrollToBottom,
|
||||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||||
isChatMonoforum,
|
isChatMonoforum,
|
||||||
@ -812,7 +813,7 @@ const MessageList = ({
|
|||||||
Content.StarsRequired
|
Content.StarsRequired
|
||||||
) : isContactRequirePremium && !hasMessages ? (
|
) : isContactRequirePremium && !hasMessages ? (
|
||||||
Content.PremiumRequired
|
Content.PremiumRequired
|
||||||
) : (isBot || isNonContact) && !hasMessages ? (
|
) : (isBot || isNonContact) && !hasMessages && threadId === MAIN_THREAD_ID ? (
|
||||||
Content.AccountInfo
|
Content.AccountInfo
|
||||||
) : shouldRenderGreeting ? (
|
) : shouldRenderGreeting ? (
|
||||||
Content.ContactGreeting
|
Content.ContactGreeting
|
||||||
@ -878,7 +879,7 @@ const MessageList = ({
|
|||||||
noAppearanceAnimation={!messageGroups || !shouldAnimateAppearanceRef.current}
|
noAppearanceAnimation={!messageGroups || !shouldAnimateAppearanceRef.current}
|
||||||
isQuickPreview={isQuickPreview}
|
isQuickPreview={isQuickPreview}
|
||||||
canPost={canPost}
|
canPost={canPost}
|
||||||
isBotForum={isBotForum}
|
canManageBotForumTopics={canManageBotForumTopics}
|
||||||
shouldScrollToBottom={shouldScrollToBottom}
|
shouldScrollToBottom={shouldScrollToBottom}
|
||||||
onScrollDownToggle={onScrollDownToggle}
|
onScrollDownToggle={onScrollDownToggle}
|
||||||
onNotchToggle={onNotchToggle}
|
onNotchToggle={onNotchToggle}
|
||||||
@ -910,6 +911,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const tabState = selectTabState(global);
|
const tabState = selectTabState(global);
|
||||||
const currentUserId = global.currentUserId!;
|
const currentUserId = global.currentUserId!;
|
||||||
const chat = selectChat(global, chatId);
|
const chat = selectChat(global, chatId);
|
||||||
|
const user = selectUser(global, chatId);
|
||||||
const userFullInfo = selectUserFullInfo(global, chatId);
|
const userFullInfo = selectUserFullInfo(global, chatId);
|
||||||
const readState = selectThreadReadState(global, chatId, threadId);
|
const readState = selectThreadReadState(global, chatId, threadId);
|
||||||
if (!chat) {
|
if (!chat) {
|
||||||
@ -1014,7 +1016,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
canTranslate,
|
canTranslate,
|
||||||
translationLanguage,
|
translationLanguage,
|
||||||
shouldAutoTranslate,
|
shouldAutoTranslate,
|
||||||
isBotForum: chat.isBotForum,
|
canManageBotForumTopics: chat.isBotForum && user?.canManageBotForumTopics,
|
||||||
shouldScrollToBottom,
|
shouldScrollToBottom,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -60,7 +60,7 @@ interface OwnProps {
|
|||||||
withUsers: boolean;
|
withUsers: boolean;
|
||||||
isChannelChat: boolean | undefined;
|
isChannelChat: boolean | undefined;
|
||||||
isChatMonoforum?: boolean;
|
isChatMonoforum?: boolean;
|
||||||
isBotForum?: boolean;
|
canManageBotForumTopics?: boolean;
|
||||||
isEmptyThread?: boolean;
|
isEmptyThread?: boolean;
|
||||||
isComments?: boolean;
|
isComments?: boolean;
|
||||||
noAvatars: boolean;
|
noAvatars: boolean;
|
||||||
@ -101,7 +101,7 @@ const MessageListContent = ({
|
|||||||
withUsers,
|
withUsers,
|
||||||
isChannelChat,
|
isChannelChat,
|
||||||
isChatMonoforum,
|
isChatMonoforum,
|
||||||
isBotForum,
|
canManageBotForumTopics,
|
||||||
noAvatars,
|
noAvatars,
|
||||||
containerRef,
|
containerRef,
|
||||||
anchorIdRef,
|
anchorIdRef,
|
||||||
@ -256,7 +256,7 @@ const MessageListContent = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderBotForumTopicAction = () => {
|
const renderBotForumTopicAction = () => {
|
||||||
if (!isBotForum || threadId !== MAIN_THREAD_ID) return undefined;
|
if (!canManageBotForumTopics || threadId !== MAIN_THREAD_ID) return undefined;
|
||||||
return (
|
return (
|
||||||
<div className={buildClassName('local-action-message', actionMessageStyles.root)} key="botforum-new-topic">
|
<div className={buildClassName('local-action-message', actionMessageStyles.root)} key="botforum-new-topic">
|
||||||
<div className={actionMessageStyles.contentBox}>
|
<div className={actionMessageStyles.contentBox}>
|
||||||
|
|||||||
@ -392,6 +392,7 @@ addActionHandler('sendMessage', async (global, actions, payload): Promise<void>
|
|||||||
}
|
}
|
||||||
|
|
||||||
const chat = selectChat(global, chatId!)!;
|
const chat = selectChat(global, chatId!)!;
|
||||||
|
const user = selectUser(global, chatId!);
|
||||||
const draft = selectDraft(global, chatId!, threadId!);
|
const draft = selectDraft(global, chatId!, threadId!);
|
||||||
const isForwarding = selectTabState(global, tabId).forwardMessages?.messageIds?.length;
|
const isForwarding = selectTabState(global, tabId).forwardMessages?.messageIds?.length;
|
||||||
|
|
||||||
@ -450,7 +451,8 @@ addActionHandler('sendMessage', async (global, actions, payload): Promise<void>
|
|||||||
suggestedMedia = suggestedMessage.content;
|
suggestedMedia = suggestedMessage.content;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chat.isBotForum && threadId === MAIN_THREAD_ID && replyInfo?.type === 'message') {
|
if (chat.isBotForum && threadId === MAIN_THREAD_ID && replyInfo?.type === 'message'
|
||||||
|
&& user?.canManageBotForumTopics) {
|
||||||
const replyMessage = selectChatMessage(global, chatId!, replyInfo.replyToMsgId);
|
const replyMessage = selectChatMessage(global, chatId!, replyInfo.replyToMsgId);
|
||||||
const replyThreadId = replyMessage && selectThreadIdFromMessage(global, replyMessage);
|
const replyThreadId = replyMessage && selectThreadIdFromMessage(global, replyMessage);
|
||||||
actions.openThread({
|
actions.openThread({
|
||||||
@ -490,7 +492,9 @@ addActionHandler('sendMessage', async (global, actions, payload): Promise<void>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create new bot forum topic
|
// Create new bot forum topic
|
||||||
if (chat.isBotForum && threadId === MAIN_THREAD_ID && replyInfo?.type !== 'message') {
|
if (chat.isBotForum && user?.canManageBotForumTopics && threadId === MAIN_THREAD_ID
|
||||||
|
&& replyInfo?.type !== 'message'
|
||||||
|
) {
|
||||||
const baseTitle = params.text ?? getTranslationFn()('BotForumTopicTitlePlaceholder');
|
const baseTitle = params.text ?? getTranslationFn()('BotForumTopicTitlePlaceholder');
|
||||||
const title = baseTitle.length > 12 ? `${baseTitle.slice(0, 12)}...` : baseTitle;
|
const title = baseTitle.length > 12 ? `${baseTitle.slice(0, 12)}...` : baseTitle;
|
||||||
const topic = await callApi('createTopic', {
|
const topic = await callApi('createTopic', {
|
||||||
|
|||||||
@ -27,7 +27,7 @@ const SAFE_MIN_PROPERTIES: (keyof ApiTopic)[] = [
|
|||||||
export function updateTopicsInfo<T extends GlobalState>(
|
export function updateTopicsInfo<T extends GlobalState>(
|
||||||
global: T, chatId: string, update: Partial<TopicsInfo>,
|
global: T, chatId: string, update: Partial<TopicsInfo>,
|
||||||
) {
|
) {
|
||||||
const info = global.chats.topicsInfoById[chatId] || {};
|
const info = global.chats.topicsInfoById[chatId] || { topicsById: {} };
|
||||||
|
|
||||||
global = {
|
global = {
|
||||||
...global,
|
...global,
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import {
|
|||||||
DEBUG, STRICTERDOM_ENABLED,
|
DEBUG, STRICTERDOM_ENABLED,
|
||||||
} from './config';
|
} from './config';
|
||||||
import { enableStrict, requestMutation } from './lib/fasterdom/fasterdom';
|
import { enableStrict, requestMutation } from './lib/fasterdom/fasterdom';
|
||||||
import { selectChat, selectChatFullInfo, selectCurrentMessageList, selectTabState } from './global/selectors';
|
import { selectChat, selectCurrentMessageList, selectPeerFullInfo, selectTabState } from './global/selectors';
|
||||||
import { selectSharedSettings } from './global/selectors/sharedState';
|
import { selectSharedSettings } from './global/selectors/sharedState';
|
||||||
import { betterView } from './util/betterView';
|
import { betterView } from './util/betterView';
|
||||||
import { IS_TAURI } from './util/browser/globalEnvironment';
|
import { IS_TAURI } from './util/browser/globalEnvironment';
|
||||||
@ -115,7 +115,7 @@ async function init() {
|
|||||||
console.warn(
|
console.warn(
|
||||||
'CURRENT MESSAGE LIST',
|
'CURRENT MESSAGE LIST',
|
||||||
selectChat(currentGlobal, currentMessageList.chatId),
|
selectChat(currentGlobal, currentMessageList.chatId),
|
||||||
selectChatFullInfo(currentGlobal, currentMessageList.chatId),
|
selectPeerFullInfo(currentGlobal, currentMessageList.chatId),
|
||||||
currentGlobal.messages.byChatId[currentMessageList.chatId],
|
currentGlobal.messages.byChatId[currentMessageList.chatId],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/types/language.d.ts
vendored
1
src/types/language.d.ts
vendored
@ -1170,6 +1170,7 @@ export interface LangPair {
|
|||||||
'ComposerPlaceholderBroadcast': undefined;
|
'ComposerPlaceholderBroadcast': undefined;
|
||||||
'ComposerPlaceholderBroadcastSilent': undefined;
|
'ComposerPlaceholderBroadcastSilent': undefined;
|
||||||
'ComposerPlaceholderTopicGeneral': undefined;
|
'ComposerPlaceholderTopicGeneral': undefined;
|
||||||
|
'ComposerPlaceholderBotTopicGeneral': undefined;
|
||||||
'ComposerStoryPlaceholderLocked': undefined;
|
'ComposerStoryPlaceholderLocked': undefined;
|
||||||
'ComposerPlaceholderNoText': undefined;
|
'ComposerPlaceholderNoText': undefined;
|
||||||
'AriaComposerCancelVoice': undefined;
|
'AriaComposerCancelVoice': undefined;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user