Forward: Add title for sticker and forward from channel (#5200)

This commit is contained in:
Alexander Zinchuk 2024-11-27 20:33:43 +04:00
parent 75bc573292
commit 20732fac61
5 changed files with 130 additions and 60 deletions

View File

@ -300,7 +300,8 @@ function buildApiMessageForwardInfo(fwdFrom: GramJs.MessageFwdHeader, isChatWith
isImported: fwdFrom.imported,
isChannelPost: Boolean(fwdFrom.channelPost),
channelPostId: fwdFrom.channelPost,
isLinkedChannelPost: Boolean(fwdFrom.channelPost && savedFromPeerId && !isChatWithSelf),
isLinkedChannelPost: Boolean(fwdFrom.channelPost && savedFromPeerId === fromId
&& fwdFrom.savedFromMsgId === fwdFrom.channelPost && !isChatWithSelf),
savedFromPeerId,
isSavedOutgoing: fwdFrom.savedOut,
fromId,

View File

@ -55,6 +55,10 @@
color: white;
background-color: var(--pattern-color);
.no-action-button & {
bottom: 0;
}
opacity: 0;
transition: opacity 150ms, backdrop-filter 150ms, filter 150ms;
@ -119,7 +123,7 @@
}
}
.is-forwarded &,
.is-forwarded:not(.custom-shape) &,
.document &,
.audio &,
.voice &,

View File

@ -529,9 +529,9 @@ const Message: FC<OwnProps & StateProps> = ({
forwardInfo
&& (!isChatWithSelf || isScheduled)
&& !isRepliesChat
&& !isAnonymousForwards
&& !forwardInfo.isLinkedChannelPost
&& !isCustomShape
&& !isAnonymousForwards
&& !botSender
) || Boolean(storyData && !storyData.isMention);
const canShowSenderBoosts = Boolean(senderBoosts) && !asForwarded && isFirstInGroup;
const isStoryMention = storyData?.isMention;
@ -548,8 +548,10 @@ const Message: FC<OwnProps & StateProps> = ({
!(isContextMenuShown || isInSelectMode || isForwarding)
&& !isInDocumentGroupNotLast
&& !isStoryMention
&& !((sticker || hasAnimatedEmoji) && asForwarded)
);
const canForward = isChannel && !isScheduled && message.isForwardingAllowed && !isChatProtected;
const canForward = isChannel && !isScheduled && message.isForwardingAllowed
&& !isChatProtected;
const canFocus = Boolean(isPinnedList
|| (forwardInfo
&& (forwardInfo.isChannelPost || isChatWithSelf || isRepliesChat || isAnonymousForwards)
@ -560,7 +562,8 @@ const Message: FC<OwnProps & StateProps> = ({
const hasFactCheck = Boolean(factCheck?.text);
const hasSubheader = hasTopicChip || hasMessageReply || hasStoryReply;
const hasForwardedCustomShape = asForwarded && isCustomShape;
const hasSubheader = hasTopicChip || hasMessageReply || hasStoryReply || hasForwardedCustomShape;
const selectMessage = useLastCallback((e?: React.MouseEvent<HTMLDivElement, MouseEvent>, groupedId?: string) => {
toggleMessageSelection({
@ -712,6 +715,7 @@ const Message: FC<OwnProps & StateProps> = ({
isJustAdded && 'is-just-added',
(hasActiveReactions || shouldPlayEffect) && 'has-active-effect',
isStoryMention && 'is-story-mention',
!canShowActionButton && 'no-action-button',
);
const text = textMessage && getMessageContent(textMessage).text;
@ -889,7 +893,7 @@ const Message: FC<OwnProps & StateProps> = ({
: undefined;
}, [isAlbum, isOwn, asForwarded, noAvatars, album, isMobile]);
const extraPadding = asForwarded ? 28 : 0;
const extraPadding = asForwarded && !isCustomShape ? 28 : 0;
const sizeCalculations = useMemo(() => {
let calculatedWidth;
@ -1074,6 +1078,7 @@ const Message: FC<OwnProps & StateProps> = ({
const className = buildClassName(
'content-inner',
asForwarded && 'forwarded-message',
hasForwardedCustomShape && 'forwarded-custom-shape',
hasSubheader && 'with-subheader',
noMediaCorners && 'no-media-corners',
);
@ -1089,7 +1094,7 @@ const Message: FC<OwnProps & StateProps> = ({
return (
<div className={className} onDoubleClick={handleContentDoubleClick} dir="auto">
{!asForwarded && renderSenderName()}
{!asForwarded && shouldRenderSenderName() && renderSenderName()}
{hasSubheader && (
<div className="message-subheader">
{hasTopicChip && (
@ -1099,6 +1104,14 @@ const Message: FC<OwnProps & StateProps> = ({
className="message-topic"
/>
)}
{hasForwardedCustomShape && (
<div className="forward-custom-shape-subheader">
<div className="message-title">
{renderForwardTitle()}
</div>
{renderSenderName(true, true)}
</div>
)}
{hasMessageReply && (
<EmbeddedMessage
message={replyMessage}
@ -1459,16 +1472,29 @@ const Message: FC<OwnProps & StateProps> = ({
return content;
}
function renderSenderName() {
function shouldRenderSenderName() {
const media = photo || video || location || paidMedia;
const shouldRender = !(isCustomShape && !viaBotId) && (
return !(isCustomShape && !viaBotId) && (
(withSenderName && (!media || hasTopicChip)) || asForwarded || viaBotId || forceSenderName
) && !isInDocumentGroupNotFirst && !(hasMessageReply && isCustomShape);
) && !isInDocumentGroupNotFirst && !(hasMessageReply && isCustomShape) && !hasSubheader;
}
if (!shouldRender) {
return undefined;
}
function renderForwardTitle() {
return (
<span className="forward-title-container">
{asForwarded && (
<Icon name={forwardInfo?.hiddenUserName ? 'forward' : 'share-filled'} />
)}
{asForwarded && (
<span className="forward-title">
{lang('ForwardedFrom')}
</span>
)}
</span>
);
}
function renderSenderName(shouldSkipRenderForwardTitle:boolean = false, shouldSkipRenderAdminTitle: boolean = false) {
let senderTitle;
let senderColor;
if (senderPeer && !(isCustomShape && viaBotId)) {
@ -1482,6 +1508,7 @@ const Message: FC<OwnProps & StateProps> = ({
const senderIsPremium = senderPeer && 'isPremium' in senderPeer && senderPeer.isPremium;
const shouldRenderForwardAvatar = asForwarded && senderPeer;
const hasBotSenderUsername = botSender?.usernames?.length;
return (
<div className="message-title" dir="ltr">
{(senderTitle || asForwarded) ? (
@ -1493,16 +1520,7 @@ const Message: FC<OwnProps & StateProps> = ({
)}
dir="ltr"
>
<span className="forward-title-container">
{asForwarded && (
<Icon name={forwardInfo?.hiddenUserName ? 'forward' : 'share-filled'} />
)}
{asForwarded && (
<span className="forward-title">
{lang('ForwardedFrom')}
</span>
)}
</span>
{!shouldSkipRenderForwardTitle && renderForwardTitle()}
<span className="message-title-name">
{storyData && <Icon name="play-story" />}
{shouldRenderForwardAvatar && (
@ -1534,21 +1552,19 @@ const Message: FC<OwnProps & StateProps> = ({
NBSP
) : undefined}
{botSender?.usernames?.length && (
<>
<span className="interactive">
<span className="via">{lang('ViaBot')}</span>
<span
className="interactive"
className="sender-title"
onClick={handleViaBotClick}
>
{renderText(`@${botSender.usernames[0].username}`)}
</span>
</>
</span>
)}
<div className="title-spacer" />
{forwardInfo?.isLinkedChannelPost ? (
{!shouldSkipRenderAdminTitle && !hasBotSenderUsername ? (forwardInfo?.isLinkedChannelPost ? (
<span className="admin-title" dir="auto">{lang('DiscussChannel')}</span>
) : message.forwardInfo?.postAuthorTitle && isGroup && asForwarded ? (
<span className="admin-title" dir="auto">{message.forwardInfo?.postAuthorTitle}</span>
) : message.postAuthorTitle && isGroup && !asForwarded ? (
<span className="admin-title" dir="auto">{message.postAuthorTitle}</span>
) : senderAdminMember && !asForwarded && !viaBotId ? (
@ -1557,7 +1573,7 @@ const Message: FC<OwnProps & StateProps> = ({
senderAdminMember.isOwner ? 'GroupInfo.LabelOwner' : 'GroupInfo.LabelAdmin',
)}
</span>
) : undefined}
) : undefined) : undefined}
{canShowSenderBoosts && (
<span className="sender-boosts" aria-hidden>
<Icon name={senderBoosts > 1 ? 'boosts' : 'boost'} />
@ -1624,7 +1640,7 @@ const Message: FC<OwnProps & StateProps> = ({
>
{asForwarded && !isInDocumentGroupNotFirst && (
<>
{renderSenderName()}
{shouldRenderSenderName() && renderSenderName()}
{forwardAuthor && <span className="admin-title" dir="auto">{forwardAuthor}</span>}
</>
)}

View File

@ -1,6 +1,25 @@
@use "sass:map";
@use "../../../styles/icons";
@mixin subheader-styles() {
font-size: calc(var(--message-text-size, 1rem) - 0.125rem);
margin-inline-end: 0.5rem;
overflow: hidden;
padding-inline: 0.4375rem;
padding-block: 0.1875rem;
border-radius: var(--border-radius-messages-small);
background-color: var(--pattern-color);
max-width: 10rem;
@media (max-width: 600px) {
max-width: calc(90vw - 13rem);
}
box-shadow: 0 1px 2px var(--color-default-shadow);
}
.message-content {
position: relative;
max-width: var(--max-width);
@ -296,6 +315,7 @@
.message-title-name-container {
flex-wrap: wrap;
padding-right: 0.25rem;
}
.forward-title-container,
@ -376,7 +396,6 @@
text-align: right;
font-weight: 400;
font-size: 0.75rem;
margin-top: -0.125rem;
color: rgba(var(--color-text-meta-rgb), 0.75);
user-select: none;
@ -403,6 +422,14 @@
padding: 0.125rem 0;
}
.message-subheader .forward-custom-shape-subheader {
@include subheader-styles();
min-width: 8rem;
.message-title {
color: white;
}
}
.message-topic {
align-self: flex-start;
}
@ -556,16 +583,20 @@
gap: 0.5rem;
& > .message-title {
display: inline-flex;
position: relative;
@include subheader-styles();
top: 0.125rem;
max-width: calc(100% - 3rem);
padding: 0 0.5rem;
background-color: var(--background-color);
border-radius: var(--border-radius-messages);
position: absolute;
left: 100%;
.Message.own & {
margin-left: -3rem;
left: initial;
right: 100%;
}
color: white;
.admin-title {
color: white;
}
}
@ -772,6 +803,16 @@
max-width: 100%;
}
.forwarded-custom-shape .message-subheader {
position: absolute;
left: 100%;
.Message.own & {
left: initial;
right: 100%;
}
}
.with-subheader {
display: flex;
align-items: flex-start;
@ -922,6 +963,24 @@
.message-content:not(.custom-shape) & {
position: relative;
margin-top: 0.25rem;
.Album,
.media-inner:not(.file-preview) {
margin-left: -0.5rem;
margin-right: -0.5rem;
body.is-ios .Message.own & {
margin-left: -0.625rem;
}
:not(.has-footer) & {
margin-bottom: -0.375rem;
body.is-ios .Message.own & {
margin-bottom: -0.4375rem;
}
}
}
}
--border-top-left-radius: 0;
@ -932,24 +991,6 @@
--border-bottom-right-radius: 0;
}
.Album,
.media-inner:not(.file-preview) {
margin-left: -0.5rem;
margin-right: -0.5rem;
body.is-ios .Message.own & {
margin-left: -0.625rem;
}
:not(.has-footer) & {
margin-bottom: -0.375rem;
body.is-ios .Message.own & {
margin-bottom: -0.4375rem;
}
}
}
.Album {
margin-bottom: 0.125rem;

View File

@ -458,9 +458,17 @@ export function selectForwardedSender<T extends GlobalState>(
if (forwardInfo.isChannelPost && forwardInfo.fromChatId) {
return selectChat(global, forwardInfo.fromChatId);
} else if (forwardInfo.fromId) {
}
if (forwardInfo.hiddenUserName) {
return undefined;
}
if (forwardInfo.fromId) {
return selectPeer(global, forwardInfo.fromId);
} else if (forwardInfo.savedFromPeerId) {
}
if (forwardInfo.savedFromPeerId) {
return selectPeer(global, forwardInfo.savedFromPeerId);
}