Composer Embedded Message: Support multi senders title in forward (#5898)
This commit is contained in:
parent
a8ab4942d0
commit
5c2e5dfcb4
@ -1953,4 +1953,5 @@
|
||||
"ApiMessageActionPaidMessagesRefundedIncoming" = "{user} refunded **{stars}** to you";
|
||||
"NotificationTitleNotSupportedInFrozenAccount" = "Your account is frozen";
|
||||
"NotificationMessageNotSupportedInFrozenAccount" = "This action is not available";
|
||||
"ComposerTitleForwardFrom" = "From: **{users}**";
|
||||
"ContextMenuItemMention" = "Mention";
|
||||
|
||||
@ -233,4 +233,10 @@
|
||||
color: var(--accent-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.is-input-forward {
|
||||
.message-title {
|
||||
font-weight: var(--font-weight-normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@ import { renderTextWithEntities } from '../helpers/renderTextWithEntities';
|
||||
|
||||
import { useFastClick } from '../../../hooks/useFastClick';
|
||||
import { useIsIntersecting } from '../../../hooks/useIntersectionObserver';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useMedia from '../../../hooks/useMedia';
|
||||
import useOldLang from '../../../hooks/useOldLang';
|
||||
import useThumbnail from '../../../hooks/useThumbnail';
|
||||
@ -49,6 +50,7 @@ type OwnProps = {
|
||||
sender?: ApiPeer;
|
||||
senderChat?: ApiChat;
|
||||
forwardSender?: ApiPeer;
|
||||
composerForwardSenders?: ApiPeer[];
|
||||
title?: string;
|
||||
customText?: string;
|
||||
noUserColors?: boolean;
|
||||
@ -72,6 +74,7 @@ const EmbeddedMessage: FC<OwnProps> = ({
|
||||
sender,
|
||||
senderChat,
|
||||
forwardSender,
|
||||
composerForwardSenders,
|
||||
title,
|
||||
customText,
|
||||
isProtected,
|
||||
@ -115,12 +118,21 @@ const EmbeddedMessage: FC<OwnProps> = ({
|
||||
chatTranslations, message?.chatId, shouldTranslate ? message?.id : undefined, requestedChatTranslationLanguage,
|
||||
);
|
||||
|
||||
const lang = useOldLang();
|
||||
const oldLang = useOldLang();
|
||||
const lang = useLang();
|
||||
|
||||
const senderTitle = sender ? getPeerTitle(lang, sender)
|
||||
const senderTitle = sender ? getPeerTitle(oldLang, sender)
|
||||
: (replyForwardInfo?.hiddenUserName || message?.forwardInfo?.hiddenUserName);
|
||||
const senderChatTitle = senderChat ? getPeerTitle(lang, senderChat) : undefined;
|
||||
const forwardSenderTitle = forwardSender ? getPeerTitle(lang, forwardSender)
|
||||
|
||||
const forwardSendersTitle = useMemo(() => {
|
||||
if (!composerForwardSenders) return undefined;
|
||||
|
||||
const peerTitles = composerForwardSenders.map((peer) => getPeerTitle(lang, peer)).filter(Boolean);
|
||||
return lang.conjunction(peerTitles);
|
||||
}, [composerForwardSenders, lang]);
|
||||
|
||||
const senderChatTitle = senderChat ? getPeerTitle(oldLang, senderChat) : undefined;
|
||||
const forwardSenderTitle = forwardSender ? getPeerTitle(oldLang, forwardSender)
|
||||
: message?.forwardInfo?.hiddenUserName;
|
||||
const areSendersSame = sender && sender.id === forwardSender?.id;
|
||||
|
||||
@ -154,7 +166,7 @@ const EmbeddedMessage: FC<OwnProps> = ({
|
||||
|
||||
function renderMediaContentType(media?: MediaContainer) {
|
||||
if (!media || media.content.text) return NBSP;
|
||||
const description = getMediaContentTypeDescription(lang, media.content, {});
|
||||
const description = getMediaContentTypeDescription(oldLang, media.content, {});
|
||||
if (!description || description === CONTENT_NOT_SUPPORTED) return NBSP;
|
||||
return (
|
||||
<span>
|
||||
@ -174,7 +186,7 @@ const EmbeddedMessage: FC<OwnProps> = ({
|
||||
return renderText(title);
|
||||
}
|
||||
|
||||
if (!senderTitle) {
|
||||
if (!senderTitle && !forwardSendersTitle) {
|
||||
return NBSP;
|
||||
}
|
||||
|
||||
@ -195,7 +207,14 @@ const EmbeddedMessage: FC<OwnProps> = ({
|
||||
<span className="embedded-sender-wrapper">
|
||||
{checkShouldRenderSenderTitle() && (
|
||||
<span className="embedded-sender">
|
||||
{renderText(isReplyToQuote ? lang('ReplyToQuote', senderTitle) : senderTitle)}
|
||||
{!composerForwardSenders && senderTitle
|
||||
&& renderText(isReplyToQuote ? oldLang('ReplyToQuote', senderTitle) : senderTitle)}
|
||||
{forwardSendersTitle && renderText(lang('ComposerTitleForwardFrom', {
|
||||
users: forwardSendersTitle,
|
||||
}, {
|
||||
withNodes: true,
|
||||
withMarkdown: true,
|
||||
}))}
|
||||
</span>
|
||||
)}
|
||||
{icon && <Icon name={icon} className="embedded-chat-icon" />}
|
||||
@ -232,6 +251,7 @@ const EmbeddedMessage: FC<OwnProps> = ({
|
||||
isQuote && 'is-quote',
|
||||
mediaThumbnail && 'with-thumb',
|
||||
'no-selection',
|
||||
composerForwardSenders && 'is-input-forward',
|
||||
)}
|
||||
dir={lang.isRtl ? 'rtl' : undefined}
|
||||
onClick={handleClick}
|
||||
|
||||
@ -2,7 +2,7 @@ import type { FC } from '../../../lib/teact/teact';
|
||||
import React, {
|
||||
memo, useEffect, useMemo, useRef,
|
||||
} from '../../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../../global';
|
||||
import { getActions, getGlobal, withGlobal } from '../../../global';
|
||||
|
||||
import type {
|
||||
ApiChat, ApiInputMessageReplyInfo, ApiMessage, ApiPeer,
|
||||
@ -21,12 +21,12 @@ import {
|
||||
selectForwardedSender,
|
||||
selectIsChatWithSelf,
|
||||
selectIsCurrentUserPremium,
|
||||
selectPeer,
|
||||
selectSender,
|
||||
selectTabState,
|
||||
} from '../../../global/selectors';
|
||||
import buildClassName from '../../../util/buildClassName';
|
||||
import captureEscKeyListener from '../../../util/captureEscKeyListener';
|
||||
import { unique } from '../../../util/iteratees';
|
||||
import { getPeerColorClass } from '../../common/helpers/peerColor';
|
||||
|
||||
import useContextMenuHandlers from '../../../hooks/useContextMenuHandlers';
|
||||
@ -63,6 +63,8 @@ type StateProps = {
|
||||
senderChat?: ApiChat;
|
||||
isSenderChannel?: boolean;
|
||||
currentUserId?: string;
|
||||
forwardMessageIds?: number[];
|
||||
fromChatId?: string;
|
||||
};
|
||||
|
||||
type OwnProps = {
|
||||
@ -96,6 +98,8 @@ const ComposerEmbeddedMessage: FC<OwnProps & StateProps> = ({
|
||||
chatId,
|
||||
currentUserId,
|
||||
isSenderChannel,
|
||||
forwardMessageIds,
|
||||
fromChatId,
|
||||
}) => {
|
||||
const {
|
||||
resetDraftReplyInfo,
|
||||
@ -120,10 +124,27 @@ const ComposerEmbeddedMessage: FC<OwnProps & StateProps> = ({
|
||||
|
||||
const isForwarding = Boolean(forwardedMessagesCount);
|
||||
|
||||
const selectSenderFromForwardedMessage = useLastCallback((forwardedMessage: ApiMessage) => {
|
||||
const global = getGlobal();
|
||||
sender = selectForwardedSender(global, forwardedMessage);
|
||||
if (!sender) {
|
||||
sender = selectSender(global, forwardedMessage);
|
||||
}
|
||||
return sender;
|
||||
});
|
||||
|
||||
const forwardSenders = useMemo(() => {
|
||||
if (!isForwarding) return undefined;
|
||||
const forwardedMessages = forwardMessageIds?.map((id) => selectChatMessage(getGlobal(), fromChatId!, id))
|
||||
.filter(Boolean);
|
||||
const senders = forwardedMessages?.map((m) => selectSenderFromForwardedMessage(m)).filter(Boolean);
|
||||
return senders ? unique(senders) : undefined;
|
||||
}, [isForwarding, forwardMessageIds, fromChatId]);
|
||||
|
||||
const isShown = (() => {
|
||||
if (isInChangingRecipientMode) return false;
|
||||
if (message && (replyInfo || editingId)) return true;
|
||||
if (sender && isForwarding) return true;
|
||||
if (forwardSenders && isForwarding) return true;
|
||||
return false;
|
||||
})();
|
||||
|
||||
@ -266,6 +287,7 @@ const ComposerEmbeddedMessage: FC<OwnProps & StateProps> = ({
|
||||
isInComposer
|
||||
message={strippedMessage}
|
||||
sender={!noAuthors ? sender : undefined}
|
||||
composerForwardSenders={forwardSenders}
|
||||
customText={customText}
|
||||
title={(editingId && !isShowingReply) ? oldLang('EditMessage')
|
||||
: noAuthors ? oldLang('HiddenSendersNameDescription') : undefined}
|
||||
@ -417,18 +439,20 @@ export default memo(withGlobal<OwnProps>(
|
||||
|
||||
let sender: ApiPeer | undefined;
|
||||
|
||||
const selectSenderFromForwardedMessage = (forwardedMessage: ApiMessage) => {
|
||||
sender = selectForwardedSender(global, forwardedMessage);
|
||||
if (!sender) {
|
||||
sender = selectSender(global, forwardedMessage);
|
||||
}
|
||||
return sender;
|
||||
};
|
||||
|
||||
if (editingId && message) {
|
||||
sender = selectSender(global, message);
|
||||
} else if (isForwarding) {
|
||||
if (message) {
|
||||
sender = selectForwardedSender(global, message);
|
||||
if (!sender) {
|
||||
sender = selectSender(global, message);
|
||||
}
|
||||
}
|
||||
if (!sender) {
|
||||
sender = selectPeer(global, fromChatId!);
|
||||
}
|
||||
let forwardSenders = forwardedMessages?.map((m) => selectSenderFromForwardedMessage(m)).filter(Boolean);
|
||||
forwardSenders = forwardSenders ? unique(forwardSenders) : undefined;
|
||||
sender = forwardSenders?.length === 1 ? forwardSenders?.[0] : undefined;
|
||||
} else if (replyInfo && message && !shouldForceShowEditing) {
|
||||
const { forwardInfo } = message;
|
||||
const isChatWithSelf = selectIsChatWithSelf(global, chatId);
|
||||
@ -471,6 +495,8 @@ export default memo(withGlobal<OwnProps>(
|
||||
senderChat,
|
||||
currentUserId: global.currentUserId,
|
||||
isSenderChannel,
|
||||
forwardMessageIds,
|
||||
fromChatId,
|
||||
};
|
||||
},
|
||||
)(ComposerEmbeddedMessage));
|
||||
|
||||
3
src/types/language.d.ts
vendored
3
src/types/language.d.ts
vendored
@ -2411,6 +2411,9 @@ export interface LangPairWithVariables<V extends unknown = LangVariable> {
|
||||
'user': V;
|
||||
'stars': V;
|
||||
};
|
||||
'ComposerTitleForwardFrom': {
|
||||
'users': V;
|
||||
};
|
||||
}
|
||||
|
||||
export interface LangPairPlural {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user