162 lines
5.2 KiB
TypeScript
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,
|
|
};
|
|
};
|