2022-11-29 12:55:09 +01:00

162 lines
5.2 KiB
TypeScript

import type {
ApiMessage, ApiChat, ApiUser, ApiDimensions,
} from '../../../api/types';
import { ApiMediaFormat } from '../../../api/types';
import {
getVideoAvatarMediaHash,
getChatAvatarHash,
getMessageMediaHash,
getMessagePhoto,
getMessageVideo,
getMessageWebPagePhoto,
getMessageWebPageVideo,
isMessageDocumentPhoto,
isMessageDocumentVideo,
getMessageMediaFormat,
getMessageMediaThumbDataUri,
getMessageFileName,
getMessageDocument,
getPhotoFullDimensions,
getVideoDimensions,
getMessageFileSize,
} from '../../../global/helpers';
import { useMemo } from '../../../lib/teact/teact';
import useMedia from '../../../hooks/useMedia';
import useMediaWithLoadProgress from '../../../hooks/useMediaWithLoadProgress';
import useBlurSync from '../../../hooks/useBlurSync';
import { MediaViewerOrigin } from '../../../types';
import { VIDEO_AVATAR_FULL_DIMENSIONS, AVATAR_FULL_DIMENSIONS } from '../../common/helpers/mediaDimensions';
type UseMediaProps = {
mediaId?: number;
message?: ApiMessage;
avatarOwner?: ApiChat | ApiUser;
origin?: MediaViewerOrigin;
lastSyncTime?: number;
delay: number | false;
};
export const useMediaProps = ({
message,
mediaId = 0,
avatarOwner,
origin,
delay,
}: UseMediaProps) => {
const photo = message ? getMessagePhoto(message) : undefined;
const video = message ? getMessageVideo(message) : undefined;
const webPagePhoto = message ? getMessageWebPagePhoto(message) : undefined;
const webPageVideo = message ? getMessageWebPageVideo(message) : undefined;
const isDocumentPhoto = message ? isMessageDocumentPhoto(message) : false;
const isDocumentVideo = message ? isMessageDocumentVideo(message) : false;
const videoSize = message ? getMessageFileSize(message) : undefined;
const avatarMedia = avatarOwner?.photos?.[mediaId];
const isVideoAvatar = Boolean(avatarMedia?.isVideo);
const isVideo = Boolean(video || webPageVideo || isDocumentVideo);
const isPhoto = Boolean(!isVideo && (photo || webPagePhoto || isDocumentPhoto));
const { isGif } = video || webPageVideo || {};
const isFromSharedMedia = origin === MediaViewerOrigin.SharedMedia;
const isFromSearch = origin === MediaViewerOrigin.SearchResult;
const getMediaHash = useMemo(() => (isFull?: boolean) => {
if (avatarOwner) {
if (avatarMedia) {
if (avatarMedia.isVideo && isFull) {
return getVideoAvatarMediaHash(avatarMedia);
} else if (mediaId === 0) {
// Show preloaded avatar if this is the first media (when user clicks on profile info avatar)
return getChatAvatarHash(avatarOwner, isFull ? 'big' : 'normal');
} else {
return `photo${avatarMedia.id}?size=c`;
}
} else {
return getChatAvatarHash(avatarOwner, isFull ? 'big' : 'normal');
}
}
return message && getMessageMediaHash(message, isFull ? 'full' : 'preview');
}, [avatarOwner, message, avatarMedia, mediaId]);
const pictogramBlobUrl = useMedia(
message
// Only use pictogram if it's already loaded
&& (isFromSharedMedia || isFromSearch || isDocumentPhoto || isDocumentVideo)
&& getMessageMediaHash(message, 'pictogram'),
undefined,
ApiMediaFormat.BlobUrl,
undefined,
delay,
);
const previewMediaHash = getMediaHash();
const previewBlobUrl = useMedia(
previewMediaHash,
undefined,
ApiMediaFormat.BlobUrl,
undefined,
delay,
);
const {
mediaData: fullMediaBlobUrl,
loadProgress,
} = useMediaWithLoadProgress(
getMediaHash(true),
undefined,
message && getMessageMediaFormat(message, 'full'),
undefined,
delay,
);
const localBlobUrl = (photo || video) ? (photo || video)!.blobUrl : undefined;
let bestImageData = (!isVideo && (localBlobUrl || fullMediaBlobUrl)) || previewBlobUrl || pictogramBlobUrl;
const thumbDataUri = useBlurSync(!bestImageData && message && getMessageMediaThumbDataUri(message));
if (!bestImageData && origin !== MediaViewerOrigin.SearchResult) {
bestImageData = thumbDataUri;
}
if (isVideoAvatar && previewBlobUrl) {
bestImageData = previewBlobUrl;
}
const bestData = localBlobUrl || fullMediaBlobUrl || (
!isVideo ? previewBlobUrl || pictogramBlobUrl || bestImageData : undefined
);
const fileName = message
? getMessageFileName(message)
: avatarOwner
? `avatar${avatarOwner!.id}.${avatarOwner?.hasVideoAvatar ? 'mp4' : 'jpg'}`
: undefined;
let dimensions!: ApiDimensions;
if (message) {
if (isDocumentPhoto || isDocumentVideo) {
dimensions = getMessageDocument(message)!.mediaSize!;
} else if (photo || webPagePhoto) {
dimensions = getPhotoFullDimensions((photo || webPagePhoto)!)!;
} else if (video || webPageVideo) {
dimensions = getVideoDimensions((video || webPageVideo)!)!;
}
} else {
dimensions = isVideoAvatar ? VIDEO_AVATAR_FULL_DIMENSIONS : AVATAR_FULL_DIMENSIONS;
}
return {
getMediaHash,
photo,
video,
webPagePhoto,
webPageVideo,
isVideo,
isPhoto,
isGif,
isDocumentPhoto,
isDocumentVideo,
fileName,
bestImageData,
bestData,
dimensions,
isFromSharedMedia,
avatarPhoto: avatarMedia,
isVideoAvatar,
loadProgress,
videoSize,
};
};