Message / Video, Web Page: Fix media overflow

This commit is contained in:
Alexander Zinchuk 2022-11-27 19:17:05 +01:00
parent 2d77f5ecf1
commit 73f112ced9
8 changed files with 65 additions and 64 deletions

View File

@ -60,11 +60,11 @@ function getMaxMessageWidthRem(fromOwnMessage: boolean, noAvatars?: boolean) {
export function getAvailableWidth(
fromOwnMessage: boolean,
isForwarded?: boolean,
isWebPagePhoto?: boolean,
asForwarded?: boolean,
isWebPageMedia?: boolean,
noAvatars?: boolean,
) {
const extraPaddingRem = isForwarded || isWebPagePhoto ? 1.625 : 0;
const extraPaddingRem = asForwarded && isWebPageMedia ? 2.25 : (asForwarded || isWebPageMedia ? 1.625 : 0);
const availableWidthRem = getMaxMessageWidthRem(fromOwnMessage, noAvatars) - extraPaddingRem;
return availableWidthRem * REM;
@ -85,21 +85,21 @@ export function calculateDimensionsForMessageMedia({
width,
height,
fromOwnMessage,
isForwarded,
isWebPagePhoto,
asForwarded,
isWebPageMedia,
isGif,
noAvatars,
}: {
width: number;
height: number;
fromOwnMessage: boolean;
isForwarded?: boolean;
isWebPagePhoto?: boolean;
asForwarded?: boolean;
isWebPageMedia?: boolean;
isGif?: boolean;
noAvatars?: boolean;
}): ApiDimensions {
const aspectRatio = height / width;
const availableWidth = getAvailableWidth(fromOwnMessage, isForwarded, isWebPagePhoto, noAvatars);
const availableWidth = getAvailableWidth(fromOwnMessage, asForwarded, isWebPageMedia, noAvatars);
const availableHeight = getAvailableHeight(isGif, aspectRatio);
const mediaWidth = isGif ? Math.max(GIF_MIN_WIDTH, width) : width;
const mediaHeight = isGif ? height * (mediaWidth / width) : height;
@ -123,8 +123,8 @@ export function getMediaViewerAvailableDimensions(withFooter: boolean, isVideo:
export function calculateInlineImageDimensions(
photo: ApiPhoto,
fromOwnMessage: boolean,
isForwarded?: boolean,
isWebPagePhoto?: boolean,
asForwarded?: boolean,
isWebPageMedia?: boolean,
noAvatars?: boolean,
) {
const { width, height } = getPhotoInlineDimensions(photo) || DEFAULT_MEDIA_DIMENSIONS;
@ -133,8 +133,8 @@ export function calculateInlineImageDimensions(
width,
height,
fromOwnMessage,
isForwarded,
isWebPagePhoto,
asForwarded,
isWebPageMedia,
noAvatars,
});
}
@ -142,7 +142,8 @@ export function calculateInlineImageDimensions(
export function calculateVideoDimensions(
video: ApiVideo,
fromOwnMessage: boolean,
isForwarded?: boolean,
asForwarded?: boolean,
isWebPageMedia?: boolean,
noAvatars?: boolean,
) {
const { width, height } = getVideoDimensions(video) || DEFAULT_MEDIA_DIMENSIONS;
@ -151,7 +152,8 @@ export function calculateVideoDimensions(
width,
height,
fromOwnMessage,
isForwarded,
asForwarded,
isWebPageMedia,
isGif: video.isGif,
noAvatars,
});

View File

@ -585,12 +585,12 @@ const Message: FC<OwnProps & StateProps> = ({
if (!isAlbum && (photo || video || invoice?.extendedMedia)) {
let width: number | undefined;
if (photo) {
width = calculateMediaDimensions(message, noAvatars).width;
width = calculateMediaDimensions(message, asForwarded, noAvatars).width;
} else if (video) {
if (video.isRound) {
width = ROUND_VIDEO_DIMENSIONS_PX;
} else {
width = calculateMediaDimensions(message, noAvatars).width;
width = calculateMediaDimensions(message, asForwarded, noAvatars).width;
}
} else if (invoice?.extendedMedia && (
invoice.extendedMedia.width && invoice.extendedMedia.height
@ -600,7 +600,7 @@ const Message: FC<OwnProps & StateProps> = ({
width: previewWidth,
height: previewHeight,
fromOwnMessage: isOwn,
isForwarded: isForwarding,
asForwarded,
noAvatars,
}).width;
}
@ -776,11 +776,12 @@ const Message: FC<OwnProps & StateProps> = ({
canAutoLoad={canAutoLoadMedia}
uploadProgress={uploadProgress}
shouldAffectAppendix={hasCustomAppendix}
onClick={handleMediaClick}
onCancelUpload={handleCancelUpload}
isDownloading={isDownloading}
isProtected={isProtected}
asForwarded={asForwarded}
theme={theme}
onClick={handleMediaClick}
onCancelUpload={handleCancelUpload}
/>
)}
{!isAlbum && video && video.isRound && (
@ -802,10 +803,11 @@ const Message: FC<OwnProps & StateProps> = ({
canAutoPlay={canAutoPlayMedia}
uploadProgress={uploadProgress}
lastSyncTime={lastSyncTime}
onClick={handleMediaClick}
onCancelUpload={handleCancelUpload}
isDownloading={isDownloading}
isProtected={isProtected}
asForwarded={asForwarded}
onClick={handleMediaClick}
onCancelUpload={handleCancelUpload}
/>
)}
{(audio || voice) && (
@ -901,12 +903,13 @@ const Message: FC<OwnProps & StateProps> = ({
noAvatars={noAvatars}
canAutoLoad={canAutoLoadMedia}
canAutoPlay={canAutoPlayMedia}
asForwarded={asForwarded}
lastSyncTime={lastSyncTime}
onMediaClick={handleMediaClick}
onCancelMediaTransfer={handleCancelUpload}
isDownloading={isDownloading}
isProtected={isProtected}
theme={theme}
onMediaClick={handleMediaClick}
onCancelMediaTransfer={handleCancelUpload}
/>
)}
{invoice && !invoice.extendedMedia && (

View File

@ -43,10 +43,10 @@ export type OwnProps = {
size?: 'inline' | 'pictogram';
shouldAffectAppendix?: boolean;
dimensions?: IMediaDimensions & { isSmall?: boolean };
asForwarded?: boolean;
nonInteractive?: boolean;
isDownloading: boolean;
isProtected?: boolean;
withAspectRatio?: boolean;
theme: ISettings['theme'];
onClick?: (id: number) => void;
onCancelUpload?: (message: ApiMessage) => void;
@ -63,11 +63,11 @@ const Photo: FC<OwnProps> = ({
uploadProgress,
size = 'inline',
dimensions,
asForwarded,
nonInteractive,
shouldAffectAppendix,
isDownloading,
isProtected,
withAspectRatio,
theme,
onClick,
onCancelUpload,
@ -148,7 +148,7 @@ const Photo: FC<OwnProps> = ({
}
}, [shouldAffectAppendix, fullMediaData, isOwn, isInSelectMode, isSelected, theme] as const);
const { width, height, isSmall } = dimensions || calculateMediaDimensions(message, noAvatars);
const { width, height, isSmall } = dimensions || calculateMediaDimensions(message, asForwarded, noAvatars);
const className = buildClassName(
'media-inner',
@ -157,10 +157,8 @@ const Photo: FC<OwnProps> = ({
width === height && 'square-image',
);
const aspectRatio = withAspectRatio ? `aspect-ratio: ${(width / height).toFixed(3)}/ 1` : '';
const style = dimensions
? `width: ${width}px; height: ${height}px; left: ${dimensions.x}px; top: ${dimensions.y}px;${aspectRatio}`
: '';
const dimensionsStyle = dimensions ? ` width: ${width}px; left: ${dimensions.x}px; top: ${dimensions.y}px;` : '';
const style = size === 'inline' ? `height: ${height}px;${dimensionsStyle}` : undefined;
return (
<div
@ -173,17 +171,11 @@ const Photo: FC<OwnProps> = ({
<img
src={fullMediaData}
className="full-media"
width={width}
height={height}
alt=""
draggable={!isProtected}
/>
{withThumb && (
<canvas
ref={thumbRef}
className={buildClassName('thumbnail', thumbClassNames)}
style={`width: ${width}px; height: ${height}px;${aspectRatio}`}
/>
<canvas ref={thumbRef} className={buildClassName('thumbnail', thumbClassNames)} />
)}
{isProtected && <span className="protector" />}
{shouldRenderSpinner && !shouldRenderDownloadButton && (

View File

@ -11,10 +11,10 @@ import { calculateVideoDimensions } from '../../common/helpers/mediaDimensions';
import {
getMediaTransferState,
getMessageMediaFormat,
getMessageMediaHash, getMessageMediaThumbDataUri,
getMessageMediaHash,
getMessageMediaThumbDataUri,
getMessageVideo,
getMessageWebPageVideo,
isForwardedMessage,
isOwnMessage,
} from '../../../global/helpers';
import type { ObserveFn } from '../../../hooks/useIntersectionObserver';
@ -41,10 +41,10 @@ export type OwnProps = {
canAutoPlay?: boolean;
uploadProgress?: number;
dimensions?: IMediaDimensions;
asForwarded?: boolean;
lastSyncTime?: number;
isDownloading: boolean;
isProtected?: boolean;
withAspectRatio?: boolean;
onClick?: (id: number) => void;
onCancelUpload?: (message: ApiMessage) => void;
};
@ -60,11 +60,11 @@ const Video: FC<OwnProps> = ({
uploadProgress,
lastSyncTime,
dimensions,
onClick,
onCancelUpload,
asForwarded,
isDownloading,
isProtected,
withAspectRatio,
onClick,
onCancelUpload,
}) => {
// eslint-disable-next-line no-null/no-null
const ref = useRef<HTMLDivElement>(null);
@ -140,8 +140,10 @@ const Video: FC<OwnProps> = ({
const duration = videoRef.current?.duration || video.duration || 0;
const isOwn = isOwnMessage(message);
const isForwarded = isForwardedMessage(message);
const { width, height } = dimensions || calculateVideoDimensions(video, isOwn, isForwarded, noAvatars);
const isWebPageVideo = Boolean(getMessageWebPageVideo(message));
const {
width, height,
} = dimensions || calculateVideoDimensions(video, isOwn, asForwarded, isWebPageVideo, noAvatars);
const handleClick = useCallback(() => {
if (isUploading) {
@ -161,9 +163,8 @@ const Video: FC<OwnProps> = ({
const className = buildClassName('media-inner dark', !isUploading && 'interactive');
const dimensionsStyle = dimensions ? ` left: ${dimensions.x}px; top: ${dimensions.y}px;` : '';
const aspectRatioStyle = withAspectRatio ? ` aspect-ratio: ${(width / height).toFixed(3)}/ 1;` : '';
const style = `width: ${width}px; height: ${height}px;${dimensionsStyle}${aspectRatioStyle}`;
const dimensionsStyle = dimensions ? ` width: ${width}px; left: ${dimensions.x}px; top: ${dimensions.y}px;` : '';
const style = `height: ${height}px;${dimensionsStyle}`;
return (
<div
@ -179,8 +180,6 @@ const Video: FC<OwnProps> = ({
src={fullMediaData}
className="full-media"
canPlay={isPlayAllowed && isIntersectingForPlaying}
width={width}
height={height}
muted
loop
playsInline

View File

@ -26,6 +26,7 @@ type OwnProps = {
canAutoLoad?: boolean;
canAutoPlay?: boolean;
inPreview?: boolean;
asForwarded?: boolean;
lastSyncTime?: number;
isDownloading?: boolean;
isProtected?: boolean;
@ -41,6 +42,7 @@ const WebPage: FC<OwnProps> = ({
canAutoLoad,
canAutoPlay,
inPreview,
asForwarded,
lastSyncTime,
isDownloading = false,
isProtected,
@ -98,13 +100,13 @@ const WebPage: FC<OwnProps> = ({
noAvatars={noAvatars}
canAutoLoad={canAutoLoad}
size={isSquarePhoto ? 'pictogram' : 'inline'}
asForwarded={asForwarded}
nonInteractive={!isMediaInteractive}
onClick={isMediaInteractive ? handleMediaClick : undefined}
onCancelUpload={onCancelMediaTransfer}
isDownloading={isDownloading}
isProtected={isProtected}
withAspectRatio
theme={theme}
onClick={isMediaInteractive ? handleMediaClick : undefined}
onCancelUpload={onCancelMediaTransfer}
/>
)}
{isArticle && (
@ -126,11 +128,11 @@ const WebPage: FC<OwnProps> = ({
canAutoLoad={canAutoLoad}
canAutoPlay={canAutoPlay}
lastSyncTime={lastSyncTime}
onClick={isMediaInteractive ? handleMediaClick : undefined}
onCancelUpload={onCancelMediaTransfer}
asForwarded={asForwarded}
isDownloading={isDownloading}
isProtected={isProtected}
withAspectRatio
onClick={isMediaInteractive ? handleMediaClick : undefined}
onCancelUpload={onCancelMediaTransfer}
/>
)}
</div>

View File

@ -93,7 +93,7 @@ function calculateContainerSize(layout: IMediaLayout[]) {
export function calculateAlbumLayout(
isOwn: boolean,
isForwarded: boolean,
asForwarded: boolean,
noAvatars: boolean,
album: IAlbum,
): IAlbumLayout {
@ -103,7 +103,7 @@ export function calculateAlbumLayout(
const averageRatio = getAverageRatio(ratios);
const albumCount = ratios.length;
const forceCalc = ratios.some((ratio) => ratio > 2);
const maxWidth = getAvailableWidth(isOwn, isForwarded, false, noAvatars) - (isForwarded ? 2.5 : 0) * REM;
const maxWidth = getAvailableWidth(isOwn, asForwarded, false, noAvatars) - (asForwarded ? 2.5 : 0) * REM;
const maxHeight = maxWidth;
let layout;

View File

@ -4,9 +4,9 @@ import {
getMessageText,
getMessagePhoto,
getMessageWebPagePhoto,
isForwardedMessage,
isOwnMessage,
getMessageVideo,
getMessageWebPageVideo,
} from '../../../../global/helpers';
const MIN_MEDIA_WIDTH = 100;
@ -22,16 +22,16 @@ export function getMinMediaWidth(hasText?: boolean, hasCommentButton?: boolean)
: (hasCommentButton ? MIN_MEDIA_WIDTH_WITH_COMMENTS : MIN_MEDIA_WIDTH);
}
export function calculateMediaDimensions(message: ApiMessage, noAvatars?: boolean) {
export function calculateMediaDimensions(message: ApiMessage, asForwarded?: boolean, noAvatars?: boolean) {
const isOwn = isOwnMessage(message);
const isForwarded = isForwardedMessage(message);
const photo = getMessagePhoto(message) || getMessageWebPagePhoto(message);
const video = getMessageVideo(message);
const isWebPagePhoto = Boolean(getMessageWebPagePhoto(message));
const isWebPageVideo = Boolean(getMessageWebPageVideo(message));
const { width, height } = photo
? calculateInlineImageDimensions(photo, isOwn, isForwarded, isWebPagePhoto, noAvatars)
: calculateVideoDimensions(video!, isOwn, isForwarded, noAvatars);
? calculateInlineImageDimensions(photo, isOwn, asForwarded, isWebPagePhoto, noAvatars)
: calculateVideoDimensions(video!, isOwn, asForwarded, isWebPageVideo, noAvatars);
const hasText = Boolean(getMessageText(message));
const minMediaWidth = getMinMediaWidth(hasText);

View File

@ -5,7 +5,10 @@
position: relative;
video,
img {
img,
canvas {
width: 100%;
height: 100%;
display: block;
object-fit: cover;
}