Show inverted media (#4677)
This commit is contained in:
parent
72e5dc177d
commit
7385d8da2f
@ -191,6 +191,8 @@ export function buildApiMessageWithChatId(
|
||||
const senderBoosts = mtpMessage.fromBoostsApplied;
|
||||
const factCheck = mtpMessage.factcheck && buildApiFactCheck(mtpMessage.factcheck);
|
||||
|
||||
const isInvertedMedia = mtpMessage.invertMedia;
|
||||
|
||||
const savedPeerId = mtpMessage.savedPeerId && getApiChatIdFromMtpPeer(mtpMessage.savedPeerId);
|
||||
|
||||
return omitUndefined<ApiMessage>({
|
||||
@ -233,6 +235,7 @@ export function buildApiMessageWithChatId(
|
||||
senderBoosts,
|
||||
viaBusinessBotId: mtpMessage.viaBusinessBotId?.toString(),
|
||||
factCheck,
|
||||
isInvertedMedia,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -606,6 +606,7 @@ export interface ApiMessage {
|
||||
savedPeerId?: string;
|
||||
senderBoosts?: number;
|
||||
factCheck?: ApiFactCheck;
|
||||
isInvertedMedia?: true;
|
||||
}
|
||||
|
||||
export interface ApiReactions {
|
||||
|
||||
@ -644,7 +644,7 @@
|
||||
|
||||
.message-content {
|
||||
&.has-replies:not(.custom-shape),
|
||||
&.text:not(.web-page) {
|
||||
&.has-footer:not(.web-page) {
|
||||
.media-inner,
|
||||
.Album {
|
||||
--border-bottom-left-radius: 0;
|
||||
@ -652,6 +652,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.text.is-inverted-media {
|
||||
.Album,
|
||||
.media-inner {
|
||||
--border-top-left-radius: 0;
|
||||
--border-top-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.has-subheader .EmbeddedMessage {
|
||||
& + .Album,
|
||||
& + .Audio,
|
||||
|
||||
@ -671,6 +671,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
giveawayResults,
|
||||
} = getMessageContent(message);
|
||||
const text = textMessage && getMessageContent(textMessage).text;
|
||||
const isInvertedMedia = Boolean(message.isInvertedMedia);
|
||||
|
||||
const { replyToMsgId, replyToPeerId, isQuote } = messageReplyInfo || {};
|
||||
const { peerId: storyReplyPeerId, storyId: storyReplyId } = storyReplyInfo || {};
|
||||
@ -703,6 +704,9 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
const withQuickReactionButton = !isTouchScreen && !phoneCall && !isInSelectMode && defaultReaction
|
||||
&& !isInDocumentGroupNotLast && !isStoryMention && !hasTtl;
|
||||
|
||||
const hasOutsideReactions = hasReactions
|
||||
&& (isCustomShape || ((photo || video || storyData || (location?.type === 'geo')) && !hasText));
|
||||
|
||||
const contentClassName = buildContentClassName(message, album, {
|
||||
hasSubheader,
|
||||
isCustomShape,
|
||||
@ -716,6 +720,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
isGeoLiveActive: location?.type === 'geoLive' && !isGeoLiveExpired(message),
|
||||
withVoiceTranscription,
|
||||
peerColorClass: getPeerColorClass(messageColorPeer, noUserColors),
|
||||
hasOutsideReactions,
|
||||
});
|
||||
|
||||
const withAppendix = contentClassName.includes('has-appendix');
|
||||
@ -726,7 +731,9 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
metaPosition = 'none';
|
||||
} else if (isInDocumentGroupNotLast) {
|
||||
metaPosition = 'none';
|
||||
} else if (hasText && !webPage && !emojiSize) {
|
||||
} else if (hasText && !webPage && !emojiSize && !isInvertedMedia) {
|
||||
metaPosition = 'in-text';
|
||||
} else if (isInvertedMedia && !emojiSize && (hasFactCheck || webPage)) {
|
||||
metaPosition = 'in-text';
|
||||
} else {
|
||||
metaPosition = 'standalone';
|
||||
@ -734,7 +741,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
|
||||
let reactionsPosition!: ReactionsPosition;
|
||||
if (hasReactions) {
|
||||
if (isCustomShape || ((photo || video || storyData || (location?.type === 'geo')) && !hasText)) {
|
||||
if (hasOutsideReactions) {
|
||||
reactionsPosition = 'outside';
|
||||
} else if (asForwarded) {
|
||||
metaPosition = 'standalone';
|
||||
@ -992,7 +999,8 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
hasSubheader && 'with-subheader',
|
||||
noMediaCorners && 'no-media-corners',
|
||||
);
|
||||
const hasCustomAppendix = isLastInGroup && !hasText && !asForwarded && !withCommentButton;
|
||||
const hasCustomAppendix = isLastInGroup
|
||||
&& (!hasText || (isInvertedMedia && !hasFactCheck && !hasReactions)) && !asForwarded && !withCommentButton;
|
||||
const textContentClass = buildClassName(
|
||||
'text-content',
|
||||
'clearfix',
|
||||
@ -1081,17 +1089,6 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
activeEmojiInteractions={activeEmojiInteractions}
|
||||
/>
|
||||
)}
|
||||
{isAlbum && (
|
||||
<Album
|
||||
album={album!}
|
||||
albumLayout={albumLayout!}
|
||||
observeIntersection={observeIntersectionForLoading}
|
||||
isOwn={isOwn}
|
||||
isProtected={isProtected}
|
||||
hasCustomAppendix={hasCustomAppendix}
|
||||
onMediaClick={handleAlbumMediaClick}
|
||||
/>
|
||||
)}
|
||||
{phoneCall && (
|
||||
<MessagePhoneCall
|
||||
message={message}
|
||||
@ -1099,23 +1096,6 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
chatId={chatId}
|
||||
/>
|
||||
)}
|
||||
{!isAlbum && photo && (
|
||||
<Photo
|
||||
message={message}
|
||||
observeIntersection={observeIntersectionForLoading}
|
||||
noAvatars={noAvatars}
|
||||
canAutoLoad={canAutoLoadMedia}
|
||||
uploadProgress={uploadProgress}
|
||||
shouldAffectAppendix={hasCustomAppendix}
|
||||
isDownloading={isDownloading}
|
||||
isProtected={isProtected}
|
||||
asForwarded={asForwarded}
|
||||
theme={theme}
|
||||
forcedWidth={contentWidth}
|
||||
onClick={handlePhotoMediaClick}
|
||||
onCancelUpload={handleCancelUpload}
|
||||
/>
|
||||
)}
|
||||
{!isAlbum && video && video.isRound && (
|
||||
<RoundVideo
|
||||
message={message}
|
||||
@ -1125,23 +1105,6 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
onReadMedia={shouldReadMedia ? handleReadMedia : undefined}
|
||||
/>
|
||||
)}
|
||||
{!isAlbum && video && !video.isRound && (
|
||||
<Video
|
||||
message={message}
|
||||
observeIntersectionForLoading={observeIntersectionForLoading}
|
||||
observeIntersectionForPlaying={observeIntersectionForPlaying}
|
||||
forcedWidth={contentWidth}
|
||||
noAvatars={noAvatars}
|
||||
canAutoLoad={canAutoLoadMedia}
|
||||
canAutoPlay={canAutoPlayMedia}
|
||||
uploadProgress={uploadProgress}
|
||||
isDownloading={isDownloading}
|
||||
isProtected={isProtected}
|
||||
asForwarded={asForwarded}
|
||||
onClick={handleVideoMediaClick}
|
||||
onCancelUpload={handleCancelUpload}
|
||||
/>
|
||||
)}
|
||||
{(audio || voice) && (
|
||||
<Audio
|
||||
theme={theme}
|
||||
@ -1222,45 +1185,31 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
</p>
|
||||
)}
|
||||
|
||||
{!hasAnimatedEmoji && hasText && (
|
||||
<div className={textContentClass} dir="auto">
|
||||
{renderMessageText()}
|
||||
{isTranslationPending && (
|
||||
<div className="translation-animation">
|
||||
<div className="text-loading">
|
||||
{renderMessageText(true)}
|
||||
</div>
|
||||
{isInvertedMedia && renderInvertedMediaContent(hasCustomAppendix)}
|
||||
|
||||
{!isInvertedMedia && (
|
||||
<>
|
||||
{renderInvertibleMediaContent(hasCustomAppendix)}
|
||||
{hasText && !hasAnimatedEmoji && (
|
||||
<div className={textContentClass} dir="auto">
|
||||
{renderMessageText()}
|
||||
{isTranslationPending && (
|
||||
<div className="translation-animation">
|
||||
<div className="text-loading">
|
||||
{renderMessageText(true)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{hasFactCheck && (
|
||||
<FactCheck factCheck={factCheck} isToggleDisabled={isInSelectMode} />
|
||||
)}
|
||||
{metaPosition === 'in-text' && renderReactionsAndMeta()}
|
||||
</div>
|
||||
)}
|
||||
{hasFactCheck && (
|
||||
<FactCheck factCheck={factCheck} isToggleDisabled={isInSelectMode} />
|
||||
)}
|
||||
{metaPosition === 'in-text' && renderReactionsAndMeta()}
|
||||
</div>
|
||||
{renderWebPage()}
|
||||
</>
|
||||
)}
|
||||
|
||||
{webPage && (
|
||||
<WebPage
|
||||
message={message}
|
||||
observeIntersectionForLoading={observeIntersectionForLoading}
|
||||
observeIntersectionForPlaying={observeIntersectionForPlaying}
|
||||
noAvatars={noAvatars}
|
||||
canAutoLoad={canAutoLoadMedia}
|
||||
canAutoPlay={canAutoPlayMedia}
|
||||
asForwarded={asForwarded}
|
||||
isDownloading={isDownloading}
|
||||
isProtected={isProtected}
|
||||
theme={theme}
|
||||
story={webPageStory}
|
||||
isConnected={isConnected}
|
||||
backgroundEmojiId={sender?.color?.backgroundEmojiId}
|
||||
shouldWarnAboutSvg={shouldWarnAboutSvg}
|
||||
autoLoadFileMaxSizeMb={autoLoadFileMaxSizeMb}
|
||||
onAudioPlay={handleAudioPlay}
|
||||
onMediaClick={handleMediaClick}
|
||||
onCancelMediaTransfer={handleCancelUpload}
|
||||
/>
|
||||
)}
|
||||
{invoice && !invoice.extendedMedia && (
|
||||
<Invoice
|
||||
message={message}
|
||||
@ -1284,6 +1233,134 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
);
|
||||
}
|
||||
|
||||
function renderInvertedMediaContent(hasCustomAppendix: boolean) {
|
||||
const textContentClass = buildClassName(
|
||||
'text-content',
|
||||
'clearfix',
|
||||
);
|
||||
const footerClass = buildClassName(
|
||||
'text-content',
|
||||
'clearfix',
|
||||
metaPosition === 'in-text' && 'with-meta',
|
||||
outgoingStatus && 'with-outgoing-icon',
|
||||
);
|
||||
|
||||
const hasMediaAfterText = isAlbum || (!isAlbum && photo) || (!isAlbum && video && !video.isRound);
|
||||
const hasContentAfterText = hasMediaAfterText || (!hasAnimatedEmoji && hasFactCheck);
|
||||
const isMetaInText = metaPosition === 'in-text';
|
||||
|
||||
return (
|
||||
<>
|
||||
{renderWebPage()}
|
||||
{hasText && !hasAnimatedEmoji && (
|
||||
<div className={textContentClass} dir="auto">
|
||||
{renderMessageText()}
|
||||
{isTranslationPending && (
|
||||
<div className="translation-animation">
|
||||
<div className="text-loading">
|
||||
{renderMessageText(true)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!hasContentAfterText && isMetaInText && renderReactionsAndMeta()}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{hasContentAfterText && (
|
||||
<>
|
||||
{renderInvertibleMediaContent(hasCustomAppendix)}
|
||||
{!hasAnimatedEmoji && (
|
||||
<div className={footerClass} dir="auto">
|
||||
{hasFactCheck && (
|
||||
<FactCheck factCheck={factCheck} isToggleDisabled={isInSelectMode} />
|
||||
)}
|
||||
{isMetaInText && renderReactionsAndMeta()}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function renderWebPage() {
|
||||
return webPage && (
|
||||
<WebPage
|
||||
message={message}
|
||||
observeIntersectionForLoading={observeIntersectionForLoading}
|
||||
observeIntersectionForPlaying={observeIntersectionForPlaying}
|
||||
noAvatars={noAvatars}
|
||||
canAutoLoad={canAutoLoadMedia}
|
||||
canAutoPlay={canAutoPlayMedia}
|
||||
asForwarded={asForwarded}
|
||||
isDownloading={isDownloading}
|
||||
isProtected={isProtected}
|
||||
theme={theme}
|
||||
story={webPageStory}
|
||||
isConnected={isConnected}
|
||||
backgroundEmojiId={sender?.color?.backgroundEmojiId}
|
||||
shouldWarnAboutSvg={shouldWarnAboutSvg}
|
||||
autoLoadFileMaxSizeMb={autoLoadFileMaxSizeMb}
|
||||
onAudioPlay={handleAudioPlay}
|
||||
onMediaClick={handleMediaClick}
|
||||
onCancelMediaTransfer={handleCancelUpload}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function renderInvertibleMediaContent(hasCustomAppendix : boolean) {
|
||||
return (
|
||||
<>
|
||||
{isAlbum && (
|
||||
<Album
|
||||
album={album!}
|
||||
albumLayout={albumLayout!}
|
||||
observeIntersection={observeIntersectionForLoading}
|
||||
isOwn={isOwn}
|
||||
isProtected={isProtected}
|
||||
hasCustomAppendix={hasCustomAppendix}
|
||||
onMediaClick={handleAlbumMediaClick}
|
||||
/>
|
||||
)}
|
||||
{!isAlbum && photo && (
|
||||
<Photo
|
||||
message={message}
|
||||
observeIntersection={observeIntersectionForLoading}
|
||||
noAvatars={noAvatars}
|
||||
canAutoLoad={canAutoLoadMedia}
|
||||
uploadProgress={uploadProgress}
|
||||
shouldAffectAppendix={hasCustomAppendix}
|
||||
isDownloading={isDownloading}
|
||||
isProtected={isProtected}
|
||||
asForwarded={asForwarded}
|
||||
theme={theme}
|
||||
forcedWidth={contentWidth}
|
||||
onClick={handlePhotoMediaClick}
|
||||
onCancelUpload={handleCancelUpload}
|
||||
/>
|
||||
)}
|
||||
{!isAlbum && video && !video.isRound && (
|
||||
<Video
|
||||
message={message}
|
||||
observeIntersectionForLoading={observeIntersectionForLoading}
|
||||
observeIntersectionForPlaying={observeIntersectionForPlaying}
|
||||
forcedWidth={contentWidth}
|
||||
noAvatars={noAvatars}
|
||||
canAutoLoad={canAutoLoadMedia}
|
||||
canAutoPlay={canAutoPlayMedia}
|
||||
uploadProgress={uploadProgress}
|
||||
isDownloading={isDownloading}
|
||||
isProtected={isProtected}
|
||||
asForwarded={asForwarded}
|
||||
onClick={handleVideoMediaClick}
|
||||
onCancelUpload={handleCancelUpload}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function renderSenderName() {
|
||||
const media = photo || video || location;
|
||||
const shouldRender = !(isCustomShape && !viaBotId) && (
|
||||
|
||||
@ -80,7 +80,7 @@
|
||||
background: none;
|
||||
}
|
||||
|
||||
.media:not(.text) &,
|
||||
.media.no-footer &,
|
||||
.Message .custom-shape &,
|
||||
.Message .invoice:not(.has-reactions) & {
|
||||
--color-accent-own: white;
|
||||
@ -98,7 +98,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.media:not(.text) &,
|
||||
.media.no-footer &,
|
||||
.Message .invoice:not(.has-reactions) & {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
@ -122,12 +122,12 @@
|
||||
padding: 0 0.375rem 0 0.3125rem;
|
||||
}
|
||||
|
||||
.is-forwarded.media:not(.text):dir(rtl) &,
|
||||
.is-forwarded.media.no-footer:dir(rtl) &,
|
||||
.Message .is-forwarded.custom-shape:dir(rtl) & {
|
||||
left: 0.8125rem;
|
||||
}
|
||||
|
||||
.is-forwarded.media:not(.text) & {
|
||||
.is-forwarded.media.no-footer & {
|
||||
bottom: 0.9375rem;
|
||||
right: 0.8125rem;
|
||||
max-width: calc(100% - 2.25rem);
|
||||
@ -152,7 +152,7 @@
|
||||
bottom: 3.375rem;
|
||||
}
|
||||
|
||||
.message-content.has-replies.text:not(.custom-shape) & {
|
||||
.message-content.has-replies.text:not(.custom-shape):not(.is-inverted-media) & {
|
||||
bottom: 3.1875rem;
|
||||
}
|
||||
|
||||
|
||||
@ -126,7 +126,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.message-content:not(.has-reactions) & {
|
||||
.message-content:not(.has-reactions):not(.is-inverted-media) & {
|
||||
margin-bottom: calc(var(--message-meta-height)) !important;
|
||||
}
|
||||
|
||||
|
||||
@ -582,6 +582,20 @@
|
||||
margin-top: -0.3125rem;
|
||||
}
|
||||
|
||||
&.text.is-inverted-media .media-inner,
|
||||
&.text.is-inverted-media .Album {
|
||||
margin-top: 0.3125rem;
|
||||
}
|
||||
|
||||
&.has-solid-background.is-inverted-media.no-footer .media-inner,
|
||||
&.has-solid-background.is-inverted-media.no-footer .Album {
|
||||
margin-bottom: -0.375rem;
|
||||
|
||||
body.is-ios .Message.own & {
|
||||
margin-bottom: -0.4375rem;
|
||||
}
|
||||
}
|
||||
|
||||
&.has-subheader .media-inner,
|
||||
&.force-sender-name .Album,
|
||||
&.has-subheader .Album,
|
||||
@ -599,8 +613,10 @@
|
||||
}
|
||||
|
||||
// Moved below `.has-subheader` to overwrite its styles
|
||||
&.text .media-inner,
|
||||
&.text .Album {
|
||||
&.is-inverted-media.has-fact-check .media-inner,
|
||||
&.is-inverted-media.has-fact-check .Album,
|
||||
&.text:not(.is-inverted-media) .media-inner,
|
||||
&.text:not(.is-inverted-media) .Album {
|
||||
margin-bottom: 0.375rem !important;
|
||||
|
||||
body.is-ios .Message.own & {
|
||||
|
||||
@ -20,6 +20,7 @@ export function buildContentClassName(
|
||||
isGeoLiveActive,
|
||||
withVoiceTranscription,
|
||||
peerColorClass,
|
||||
hasOutsideReactions,
|
||||
}: {
|
||||
hasSubheader?: boolean;
|
||||
isCustomShape?: boolean | number;
|
||||
@ -33,6 +34,7 @@ export function buildContentClassName(
|
||||
isGeoLiveActive?: boolean;
|
||||
withVoiceTranscription?: boolean;
|
||||
peerColorClass?: string;
|
||||
hasOutsideReactions?: boolean;
|
||||
} = {},
|
||||
) {
|
||||
const {
|
||||
@ -42,12 +44,25 @@ export function buildContentClassName(
|
||||
const text = album?.hasMultipleCaptions ? undefined : getMessageContent(album?.captionMessage || message).text;
|
||||
const hasFactCheck = Boolean(message.factCheck?.text);
|
||||
|
||||
const isInvertedMedia = message.isInvertedMedia;
|
||||
const isInvertibleMedia = photo || (video && !video?.isRound) || album || webPage;
|
||||
|
||||
const classNames = [MESSAGE_CONTENT_CLASS_NAME];
|
||||
const isMedia = storyData || photo || video || location || invoice?.extendedMedia;
|
||||
const hasText = text || location?.type === 'venue' || isGeoLiveActive || hasFactCheck;
|
||||
const isMediaWithNoText = isMedia && !hasText;
|
||||
const isViaBot = Boolean(message.viaBotId);
|
||||
|
||||
const hasFooter = (() => {
|
||||
if (isInvertedMedia && isInvertibleMedia) {
|
||||
if (hasReactions && !hasOutsideReactions) return true;
|
||||
if (hasFactCheck) return true;
|
||||
if (webPage && hasText) return true;
|
||||
return false;
|
||||
}
|
||||
return hasText;
|
||||
})();
|
||||
|
||||
if (peerColorClass) {
|
||||
classNames.push(peerColorClass);
|
||||
}
|
||||
@ -130,6 +145,10 @@ export function buildContentClassName(
|
||||
classNames.push('has-reactions');
|
||||
}
|
||||
|
||||
if (hasOutsideReactions) {
|
||||
classNames.push('has-outside-reactions');
|
||||
}
|
||||
|
||||
if (isViaBot) {
|
||||
classNames.push('is-via-bot');
|
||||
}
|
||||
@ -149,10 +168,24 @@ export function buildContentClassName(
|
||||
classNames.push('has-solid-background');
|
||||
}
|
||||
|
||||
if (hasFactCheck) {
|
||||
classNames.push('has-fact-check');
|
||||
}
|
||||
|
||||
if (isLastInGroup && (photo || !isMediaWithNoText || (location && asForwarded))) {
|
||||
classNames.push('has-appendix');
|
||||
}
|
||||
}
|
||||
|
||||
if (isInvertibleMedia && isInvertedMedia) {
|
||||
classNames.push('is-inverted-media');
|
||||
}
|
||||
|
||||
if (hasFooter) {
|
||||
classNames.push('has-footer');
|
||||
} else {
|
||||
classNames.push('no-footer');
|
||||
}
|
||||
|
||||
return classNames.join(' ');
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user