2024-08-06 20:06:04 +02:00

137 lines
3.8 KiB
TypeScript

import { useMemo } from '../../../lib/teact/teact';
import type { MediaViewerMedia } from '../../../types';
import { ApiMediaFormat } from '../../../api/types';
import { MediaViewerOrigin } from '../../../types';
import {
getMediaFileSize,
getMediaFormat,
getMediaHash,
getMediaThumbUri,
getPhotoFullDimensions,
getVideoAvatarMediaHash,
getVideoDimensions,
isDocumentPhoto,
isDocumentVideo,
} from '../../../global/helpers';
import { AVATAR_FULL_DIMENSIONS, VIDEO_AVATAR_FULL_DIMENSIONS } from '../../common/helpers/mediaDimensions';
import useBlurSync from '../../../hooks/useBlurSync';
import useMedia from '../../../hooks/useMedia';
import useMediaWithLoadProgress from '../../../hooks/useMediaWithLoadProgress';
const FALLBACK_DIMENSIONS = AVATAR_FULL_DIMENSIONS;
type UseMediaProps = {
media?: MediaViewerMedia;
isAvatar?: boolean;
origin?: MediaViewerOrigin;
delay: number | false;
};
export const useMediaProps = ({
media,
isAvatar,
origin,
delay,
}: UseMediaProps) => {
const isVideoAvatar = isAvatar && media?.mediaType === 'photo' && media.isVideo;
const isDocument = media?.mediaType === 'document';
const isVideo = (media?.mediaType === 'video' && !media.isRound) || (isDocument && isDocumentVideo(media));
const isPhoto = media?.mediaType === 'photo' || (isDocument && isDocumentPhoto(media));
const isGif = media?.mediaType === 'video' && media.isGif;
const isFromSharedMedia = origin === MediaViewerOrigin.SharedMedia;
const isFromSearch = origin === MediaViewerOrigin.SearchResult;
const getMediaOrAvatarHash = useMemo(() => (isFull?: boolean) => {
if (!media) return undefined;
if (isVideoAvatar && isFull) {
return getVideoAvatarMediaHash(media);
}
return getMediaHash(media, isFull ? 'full' : 'preview');
}, [isVideoAvatar, media]);
const pictogramBlobUrl = useMedia(
media
// Only use pictogram if it's already loaded
&& (isFromSharedMedia || isFromSearch || isDocument)
&& getMediaHash(media, 'pictogram'),
undefined,
ApiMediaFormat.BlobUrl,
delay,
);
const previewMediaHash = getMediaOrAvatarHash();
const previewBlobUrl = useMedia(
previewMediaHash,
undefined,
ApiMediaFormat.BlobUrl,
delay,
);
const {
mediaData: fullMediaBlobUrl,
loadProgress,
} = useMediaWithLoadProgress(
getMediaOrAvatarHash(true),
undefined,
media && getMediaFormat(media, 'full'),
delay,
);
const localBlobUrl = media && 'blobUrl' in media ? media.blobUrl : undefined;
let bestImageData = (!isVideo && (localBlobUrl || fullMediaBlobUrl)) || previewBlobUrl || pictogramBlobUrl;
const thumbDataUri = useBlurSync(!bestImageData && media && getMediaThumbUri(media));
if (!bestImageData && origin !== MediaViewerOrigin.SearchResult) {
bestImageData = thumbDataUri;
}
if (isVideoAvatar && previewBlobUrl) {
bestImageData = previewBlobUrl;
}
const bestData = localBlobUrl || fullMediaBlobUrl || (
(!isVideoAvatar && !isVideo) ? (previewBlobUrl || pictogramBlobUrl || bestImageData) : undefined
);
const mediaSize = media && getMediaFileSize(media);
const isLocal = Boolean(localBlobUrl);
const dimensions = useMemo(() => {
if (isAvatar) {
return isVideoAvatar ? VIDEO_AVATAR_FULL_DIMENSIONS : AVATAR_FULL_DIMENSIONS;
}
if (isDocument) {
return media.mediaSize!;
}
if (isPhoto) {
return getPhotoFullDimensions(media);
}
if (isVideo) {
return getVideoDimensions(media);
}
return FALLBACK_DIMENSIONS;
}, [isAvatar, isDocument, isPhoto, isVideo, isVideoAvatar, media]);
return {
getMediaHash: getMediaOrAvatarHash,
media,
isVideo,
isPhoto,
isGif,
isDocument,
bestImageData,
bestData,
dimensions,
isFromSharedMedia,
isVideoAvatar,
isLocal,
loadProgress,
mediaSize,
};
};