Message: Show guest bots (#6955)
This commit is contained in:
parent
60f3995e82
commit
b7e10507e6
@ -199,7 +199,7 @@ export function buildApiMessageWithChatId(
|
||||
const isPrivateChat = getEntityTypeById(chatId) === 'user';
|
||||
// Server can return `fromId` for our own messages in private chats, but not for incoming ones
|
||||
// This can break grouping logic, as we do not fill `fromId` for `UpdateShortMessage` case
|
||||
const fromId = mtpMessage.fromId && !isPrivateChat
|
||||
const fromId = mtpMessage.fromId && (!isPrivateChat || mtpMessage.guestchatViaFrom)
|
||||
? getApiChatIdFromMtpPeer(mtpMessage.fromId) : undefined;
|
||||
|
||||
const isChatWithSelf = !fromId && chatId === currentUserId;
|
||||
@ -299,6 +299,7 @@ export function buildApiMessageWithChatId(
|
||||
restrictionReasons,
|
||||
summaryLanguageCode: mtpMessage.summaryFromLanguage,
|
||||
fromRank: mtpMessage.fromRank,
|
||||
guestChatViaId: mtpMessage.guestchatViaFrom && getApiChatIdFromMtpPeer(mtpMessage.guestchatViaFrom),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -116,7 +116,7 @@ export function buildApiUser(mtpUser: GramJs.TypeUser): ApiUser | undefined {
|
||||
const {
|
||||
id, firstName, lastName, fake, scam, support, closeFriend, storiesUnavailable,
|
||||
bot, botActiveUsers, botVerificationIcon, botInlinePlaceholder, botAttachMenu, botCanEdit,
|
||||
sendPaidMessagesStars, profileColor, botForumView, botForumCanManageTopics,
|
||||
sendPaidMessagesStars, profileColor, botForumView, botForumCanManageTopics, botGuestchat,
|
||||
} = mtpUser;
|
||||
const storiesMaxId = mtpUser.storiesMaxId?.maxId;
|
||||
const hasVideoAvatar = mtpUser.photo instanceof GramJs.UserProfilePhoto ? Boolean(mtpUser.photo.hasVideo) : undefined;
|
||||
@ -162,6 +162,7 @@ export function buildApiUser(mtpUser: GramJs.TypeUser): ApiUser | undefined {
|
||||
paidMessagesStars: toJSNumber(sendPaidMessagesStars),
|
||||
isBotForum: botForumView,
|
||||
canManageBotForumTopics: botForumCanManageTopics,
|
||||
isGuestChatBot: botGuestchat,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -764,6 +764,7 @@ export interface ApiMessage {
|
||||
isKeyboardSelective?: boolean;
|
||||
viaBotId?: string;
|
||||
viaBusinessBotId?: string;
|
||||
guestChatViaId?: string;
|
||||
postAuthorTitle?: string;
|
||||
isScheduled?: boolean;
|
||||
scheduleRepeatPeriod?: number;
|
||||
|
||||
@ -49,6 +49,7 @@ export interface ApiUser {
|
||||
paidMessagesStars?: number;
|
||||
isBotForum?: boolean;
|
||||
canManageBotForumTopics?: boolean;
|
||||
isGuestChatBot?: boolean;
|
||||
}
|
||||
|
||||
export interface ApiUserFullInfo {
|
||||
|
||||
@ -816,6 +816,7 @@
|
||||
"PaymentInvoiceNotFound" = "Invoice not found";
|
||||
"NoWordsRecognized" = "No words recognized.";
|
||||
"ViaBot" = "via";
|
||||
"ForBot" = "for";
|
||||
"DiscussChannel" = "channel";
|
||||
"ForwardedMessage" = "Forwarded message";
|
||||
"ContextForwardMsg" = "Forward";
|
||||
|
||||
@ -23,6 +23,7 @@ import { getPeerTitle } from '../../global/helpers/peers';
|
||||
import { selectChatMessage, selectSender } from '../../global/selectors';
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
import { formatHumanDate, formatScheduledDateTime } from '../../util/dates/oldDateFormat';
|
||||
import { isUserId } from '../../util/entities/ids';
|
||||
import { convertTonFromNanos } from '../../util/formatCurrency';
|
||||
import { compact } from '../../util/iteratees';
|
||||
import { formatMessageListDate } from '../../util/localization/dateFormat';
|
||||
@ -134,6 +135,7 @@ const MessageListContent = ({
|
||||
const getIsReady = useDerivedSignal(() => isReady && !getIsHeavyAnimating2(), [isReady, getIsHeavyAnimating2]);
|
||||
|
||||
const areDatesClickable = !isSavedDialog && !isSchedule;
|
||||
const isPrivate = isUserId(chatId);
|
||||
const shouldRenderSponsoredMessage = canShowAds && isViewportNewest;
|
||||
const shouldHideComments = hasLinkedChat === false || !isChannelChat || Boolean(isChatMonoforum);
|
||||
|
||||
@ -352,6 +354,7 @@ const MessageListContent = ({
|
||||
const originalId = getMessageOriginalId(message);
|
||||
const key = isServiceNotificationMessage(message)
|
||||
? `${message.date}_${originalId}` : originalId;
|
||||
const shouldShowGuestAvatar = isPrivate && !withUsers && Boolean(message.guestChatViaId);
|
||||
|
||||
return compact([
|
||||
message.id === memoUnreadDividerBeforeIdRef.current && unreadDivider,
|
||||
@ -365,9 +368,10 @@ const MessageListContent = ({
|
||||
observeIntersectionForPlaying={observeIntersectionForPlaying}
|
||||
album={album}
|
||||
documentGroup={documentGroup}
|
||||
noAvatars={noAvatars}
|
||||
withAvatar={position.isLastInGroup && withUsers && !isOwn && (!isThreadTopMessage || !isComments)}
|
||||
withSenderName={position.isFirstInGroup && withUsers && !isOwn}
|
||||
noAvatars={noAvatars && !shouldShowGuestAvatar}
|
||||
withAvatar={position.isLastInGroup && (withUsers || shouldShowGuestAvatar)
|
||||
&& !isOwn && (!isThreadTopMessage || !isComments)}
|
||||
withSenderName={position.isFirstInGroup && (withUsers || shouldShowGuestAvatar) && !isOwn}
|
||||
threadId={threadId}
|
||||
messageListType={type}
|
||||
noComments={shouldHideComments}
|
||||
@ -450,8 +454,6 @@ const MessageListContent = ({
|
||||
return renderMessageElement(message, position, isThreadTopMessage, album);
|
||||
}).flat();
|
||||
|
||||
if (!withUsers) return senderGroupElements;
|
||||
|
||||
const lastItem = senderGroup[senderGroup.length - 1];
|
||||
const lastMessage = isAlbum(lastItem)
|
||||
? lastItem.mainMessage
|
||||
@ -474,11 +476,14 @@ const MessageListContent = ({
|
||||
const isThreadTopMessage = lastMessage.id === threadId
|
||||
|| (firstMessage.id === threadId && Boolean(firstMessage.groupedId));
|
||||
|
||||
const shouldShowGuestAvatar = isPrivate && !withUsers && Boolean(lastMessage.guestChatViaId);
|
||||
if (!withUsers && !shouldShowGuestAvatar) return senderGroupElements;
|
||||
|
||||
const key = `${firstMessageId}-${lastMessageId}`;
|
||||
const id = (firstMessageId === lastMessageId) ? `message-group-${firstMessageId}`
|
||||
: `message-group-${firstMessageId}-${lastMessageId}`;
|
||||
|
||||
const withAvatar = withUsers && !isOwn && (!isThreadTopMessage || !isComments);
|
||||
const withAvatar = (withUsers || shouldShowGuestAvatar) && !isOwn && (!isThreadTopMessage || !isComments);
|
||||
return compact([
|
||||
<SenderGroupContainer
|
||||
key={key}
|
||||
|
||||
@ -121,6 +121,7 @@ export function groupMessages(
|
||||
} else if (
|
||||
nextMessage.id === firstUnreadId
|
||||
|| message.senderId !== nextMessage.senderId
|
||||
|| message.guestChatViaId !== nextMessage.guestChatViaId
|
||||
|| (!withUsers && message.paidMessageStars)
|
||||
|| (nextMessage.suggestedPostInfo)
|
||||
|| message.isOutgoing !== nextMessage.isOutgoing
|
||||
|
||||
@ -154,6 +154,10 @@
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
&.has-guest-avatar {
|
||||
padding-left: 2.5rem;
|
||||
}
|
||||
|
||||
&.first-in-group:not(.last-in-group) {
|
||||
--border-bottom-left-radius: var(--border-radius-messages-small);
|
||||
}
|
||||
@ -182,6 +186,10 @@
|
||||
&.is-thread-top {
|
||||
padding-left: 0.25rem;
|
||||
}
|
||||
|
||||
&.has-guest-avatar {
|
||||
padding-left: 2.875rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -72,7 +72,7 @@ import {
|
||||
isReplyToMessage,
|
||||
isSystemBot,
|
||||
} from '../../../global/helpers';
|
||||
import { getPeerFullTitle } from '../../../global/helpers/peers';
|
||||
import { getPeerFullTitle, getPeerTitle } from '../../../global/helpers/peers';
|
||||
import { getMessageReplyInfo, getStoryReplyInfo } from '../../../global/helpers/replies';
|
||||
import {
|
||||
selectActiveDownloads,
|
||||
@ -329,6 +329,7 @@ type StateProps = {
|
||||
tags?: Record<ApiReactionKey, ApiSavedReactionTag>;
|
||||
canTranscribeVoice?: boolean;
|
||||
viaBusinessBot?: ApiUser;
|
||||
guestFromSender?: ApiPeer;
|
||||
effect?: ApiAvailableEffect;
|
||||
poll?: ApiMessagePoll;
|
||||
webPage?: ApiWebPage;
|
||||
@ -459,6 +460,7 @@ const Message = ({
|
||||
tags,
|
||||
canTranscribeVoice,
|
||||
viaBusinessBot,
|
||||
guestFromSender,
|
||||
effect,
|
||||
poll,
|
||||
maxTimestamp,
|
||||
@ -503,7 +505,7 @@ const Message = ({
|
||||
const oldLang = useOldLang();
|
||||
const lang = useLang();
|
||||
const {
|
||||
id: messageId, chatId, forwardInfo, viaBotId, isTranscriptionError, factCheck,
|
||||
id: messageId, chatId, forwardInfo, viaBotId, guestChatViaId, isTranscriptionError, factCheck,
|
||||
isTypingDraft, previousLocalId, fromRank,
|
||||
} = message;
|
||||
|
||||
@ -600,13 +602,15 @@ const Message = ({
|
||||
const isCustomShape = !withVoiceTranscription && getMessageCustomShape(message);
|
||||
const hasAnimatedEmoji = isCustomShape && (animatedEmoji || animatedCustomEmoji);
|
||||
const hasReactions = reactionMessage?.reactions && !areReactionsEmpty(reactionMessage.reactions);
|
||||
const hasViaSender = Boolean(viaBotId || guestChatViaId);
|
||||
|
||||
const asForwarded = (
|
||||
forwardInfo
|
||||
&& (!isChatWithSelf || isScheduled)
|
||||
&& !isRepliesChat
|
||||
&& !forwardInfo.isLinkedChannelPost
|
||||
&& !isAnonymousForwards
|
||||
&& !botSender
|
||||
&& !hasViaSender
|
||||
) || Boolean(storyData && !storyData.isMention);
|
||||
const canShowSenderBoosts = Boolean(senderBoosts) && !asForwarded && isFirstInGroup;
|
||||
const isStoryMention = storyData?.isMention;
|
||||
@ -691,6 +695,7 @@ const Message = ({
|
||||
const {
|
||||
handleSenderClick,
|
||||
handleViaBotClick,
|
||||
handleGuestForClick,
|
||||
handleReplyClick,
|
||||
handleMediaClick,
|
||||
handleDocumentClick,
|
||||
@ -724,6 +729,7 @@ const Message = ({
|
||||
avatarPeer,
|
||||
senderPeer,
|
||||
botSender,
|
||||
guestFromSender,
|
||||
messageTopic,
|
||||
isTranslatingChat: Boolean(requestedChatTranslationLanguage),
|
||||
story: replyStory && 'content' in replyStory ? replyStory : undefined,
|
||||
@ -815,6 +821,7 @@ const Message = ({
|
||||
isJustAdded && 'is-just-added',
|
||||
(hasActiveReactions || shouldPlayEffect) && 'has-active-effect',
|
||||
isStoryMention && 'is-story-mention',
|
||||
guestChatViaId && 'has-guest-avatar',
|
||||
);
|
||||
|
||||
const text = textMessage && getMessageContent(textMessage).text;
|
||||
@ -1655,8 +1662,9 @@ const Message = ({
|
||||
|
||||
function shouldRenderSenderName() {
|
||||
const media = photo || video || location || paidMedia;
|
||||
return !(isCustomShape && !viaBotId) && (
|
||||
(withSenderName && (!media || hasTopicChip)) || asForwarded || viaBotId || forceSenderName
|
||||
return !(isCustomShape && !hasViaSender) && (
|
||||
(withSenderName && (!media || hasTopicChip)) || asForwarded || viaBotId
|
||||
|| (guestChatViaId && isFirstInGroup) || forceSenderName
|
||||
) && !isInDocumentGroupNotFirst && !(hasMessageReply && isCustomShape);
|
||||
}
|
||||
|
||||
@ -1734,7 +1742,7 @@ const Message = ({
|
||||
shouldSkipRenderForwardTitle: boolean = false, shouldSkipRenderAdminTitle: boolean = false,
|
||||
) {
|
||||
let senderTitle;
|
||||
if (senderPeer && !(isCustomShape && viaBotId)) {
|
||||
if (senderPeer && !(isCustomShape && hasViaSender)) {
|
||||
senderTitle = getPeerFullTitle(oldLang, senderPeer);
|
||||
} else if (forwardInfo?.hiddenUserName) {
|
||||
senderTitle = forwardInfo.hiddenUserName;
|
||||
@ -1743,6 +1751,7 @@ const Message = ({
|
||||
}
|
||||
const senderEmojiStatus = senderPeer && 'emojiStatus' in senderPeer && senderPeer.emojiStatus;
|
||||
const senderIsPremium = senderPeer && 'isPremium' in senderPeer && senderPeer.isPremium;
|
||||
const guestFromSenderTitle = guestFromSender ? getPeerTitle(oldLang, guestFromSender) : undefined;
|
||||
|
||||
const shouldRenderForwardAvatar = asForwarded && senderPeer;
|
||||
return (
|
||||
@ -1784,12 +1793,12 @@ const Message = ({
|
||||
{senderPeer?.fakeType && <FakeIcon fakeType={senderPeer.fakeType} />}
|
||||
</span>
|
||||
</span>
|
||||
) : !botSender ? (
|
||||
) : (!botSender && !guestFromSender) ? (
|
||||
NBSP
|
||||
) : undefined}
|
||||
{botSender?.hasUsername && (
|
||||
<span className="interactive">
|
||||
<span className="via">{oldLang('ViaBot')}</span>
|
||||
<span className="interactive via-sender">
|
||||
<span className="via">{lang('ViaBot')}</span>
|
||||
<span
|
||||
className="sender-title"
|
||||
onClick={handleViaBotClick}
|
||||
@ -1798,6 +1807,17 @@ const Message = ({
|
||||
</span>
|
||||
</span>
|
||||
)}
|
||||
{guestFromSenderTitle && (
|
||||
<span className="interactive via-sender">
|
||||
<span className="via">{lang('ForBot')}</span>
|
||||
<span
|
||||
className="sender-title"
|
||||
onClick={handleGuestForClick}
|
||||
>
|
||||
{renderText(guestFromSenderTitle)}
|
||||
</span>
|
||||
</span>
|
||||
)}
|
||||
<div className="title-spacer" />
|
||||
{((!shouldSkipRenderAdminTitle && !signature) || canShowSenderBoosts) && (
|
||||
<span className="message-title-meta">
|
||||
@ -2083,8 +2103,8 @@ export default memo(withGlobal<OwnProps>(
|
||||
isLastInDocumentGroup, isFirstInGroup,
|
||||
} = ownProps;
|
||||
const {
|
||||
id, chatId, viaBotId, isOutgoing, forwardInfo, transcriptionId, isPinned, viaBusinessBotId, effectId,
|
||||
paidMessageStars,
|
||||
id, chatId, viaBotId, guestChatViaId, isOutgoing, forwardInfo, transcriptionId, isPinned,
|
||||
viaBusinessBotId, effectId, paidMessageStars,
|
||||
} = message;
|
||||
|
||||
const webPage = selectFullWebPageFromMessage(global, message);
|
||||
@ -2112,6 +2132,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
const sender = selectSender(global, message);
|
||||
const originSender = selectForwardedSender(global, message);
|
||||
const botSender = viaBotId ? selectUser(global, viaBotId) : undefined;
|
||||
const guestFromSender = guestChatViaId ? selectPeer(global, guestChatViaId) : undefined;
|
||||
const senderChatMember = sender?.id
|
||||
? (adminMembersById?.[sender?.id] || members?.find((member) => member.userId === sender?.id))
|
||||
: undefined;
|
||||
@ -2234,6 +2255,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
canShowSender,
|
||||
originSender,
|
||||
botSender,
|
||||
guestFromSender,
|
||||
shouldHideReply: shouldHideReply || isReplyToTopicStart,
|
||||
replyMessage,
|
||||
replyMessageSender,
|
||||
|
||||
@ -354,6 +354,12 @@
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.via-sender {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.sender-hidden {
|
||||
font-weight: normal;
|
||||
}
|
||||
@ -639,6 +645,9 @@
|
||||
.MessageList.no-avatars & {
|
||||
max-width: min(29rem, calc(100vw - 3.75rem));
|
||||
}
|
||||
.has-guest-avatar & {
|
||||
max-width: min(29rem, calc(100vw - 6.25rem));
|
||||
}
|
||||
.Message.own & {
|
||||
max-width: min(30rem, calc(100vw - 3.75rem));
|
||||
}
|
||||
@ -649,6 +658,9 @@
|
||||
.MessageList.no-avatars & {
|
||||
max-width: min(29rem, calc(100vw - 4.5rem));
|
||||
}
|
||||
.has-guest-avatar & {
|
||||
max-width: min(29rem, calc(100vw - 7rem));
|
||||
}
|
||||
|
||||
.Message.own & {
|
||||
max-width: min(30rem, calc(100vw - 4.5rem));
|
||||
|
||||
@ -67,7 +67,7 @@ export function buildContentClassName(
|
||||
const hasText = text || location?.mediaType === 'venue' || isGeoLiveActive || hasFactCheck || poll;
|
||||
const isMediaWithNoText = isMedia && !hasText;
|
||||
const hasInlineKeyboard = Boolean(message.inlineButtons);
|
||||
const isViaBot = Boolean(message.viaBotId);
|
||||
const isViaBot = Boolean(message.viaBotId || message.guestChatViaId);
|
||||
|
||||
const hasFooter = (() => {
|
||||
if (isInvertedMedia && isInvertibleMedia) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { getActions } from '../../../../global';
|
||||
|
||||
import type { ApiMessage, ApiPeer, ApiStory, ApiTopic, ApiUser, ApiWebPage } from '../../../../api/types';
|
||||
import type { ApiMessage, ApiPeer, ApiStory, ApiTopic, ApiWebPage } from '../../../../api/types';
|
||||
import type { OldLangFn } from '../../../../hooks/useOldLang';
|
||||
import type { IAlbum, ThreadId } from '../../../../types';
|
||||
import { MAIN_THREAD_ID } from '../../../../api/types';
|
||||
@ -25,6 +25,7 @@ export default function useInnerHandlers({
|
||||
album,
|
||||
senderPeer,
|
||||
botSender,
|
||||
guestFromSender,
|
||||
messageTopic,
|
||||
isTranslatingChat,
|
||||
story,
|
||||
@ -45,7 +46,8 @@ export default function useInnerHandlers({
|
||||
album?: IAlbum;
|
||||
avatarPeer?: ApiPeer;
|
||||
senderPeer?: ApiPeer;
|
||||
botSender?: ApiUser;
|
||||
botSender?: ApiPeer;
|
||||
guestFromSender?: ApiPeer;
|
||||
messageTopic?: ApiTopic;
|
||||
isTranslatingChat?: boolean;
|
||||
story?: ApiStory;
|
||||
@ -83,7 +85,8 @@ export default function useInnerHandlers({
|
||||
});
|
||||
|
||||
const handleViaBotClick = useLastCallback(() => {
|
||||
if (!botSender) {
|
||||
const username = botSender && getMainUsername(botSender);
|
||||
if (!username) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -91,11 +94,19 @@ export default function useInnerHandlers({
|
||||
chatId,
|
||||
threadId,
|
||||
text: {
|
||||
text: `@${getMainUsername(botSender)} `,
|
||||
text: `@${username} `,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
const handleGuestForClick = useLastCallback(() => {
|
||||
if (!guestFromSender) {
|
||||
return;
|
||||
}
|
||||
|
||||
openChat({ id: guestFromSender.id });
|
||||
});
|
||||
|
||||
const handleReplyClick = useLastCallback((): void => {
|
||||
if (!replyToMsgId || isReplyPrivate) {
|
||||
showNotification({
|
||||
@ -289,6 +300,7 @@ export default function useInnerHandlers({
|
||||
return {
|
||||
handleSenderClick,
|
||||
handleViaBotClick,
|
||||
handleGuestForClick,
|
||||
handleReplyClick,
|
||||
handleDocumentClick,
|
||||
handleMediaClick,
|
||||
|
||||
@ -112,8 +112,10 @@ export function getPeerFullTitle(lang: OldLangFn | LangFn, peer: ApiPeer | Custo
|
||||
}
|
||||
|
||||
export function getMessageSenderName(lang: LangFn, chatId: string, sender: ApiPeer) {
|
||||
const isSenderUser = isApiPeerUser(sender);
|
||||
const isSenderGuestBot = isSenderUser && sender.isGuestChatBot;
|
||||
// Hide sender name for private chats
|
||||
if (isUserId(chatId)) return undefined;
|
||||
if (isUserId(chatId) && !isSenderGuestBot) return undefined;
|
||||
|
||||
if (isApiPeerChat(sender)) {
|
||||
if (chatId === sender.id) return undefined;
|
||||
|
||||
1
src/types/language.d.ts
vendored
1
src/types/language.d.ts
vendored
@ -709,6 +709,7 @@ export interface LangPair {
|
||||
'PaymentInvoiceNotFound': undefined;
|
||||
'NoWordsRecognized': undefined;
|
||||
'ViaBot': undefined;
|
||||
'ForBot': undefined;
|
||||
'DiscussChannel': undefined;
|
||||
'ForwardedMessage': undefined;
|
||||
'ContextForwardMsg': undefined;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user