82 lines
2.8 KiB
TypeScript
82 lines
2.8 KiB
TypeScript
import { useMemo } from '../lib/teact/teact';
|
|
|
|
import type {
|
|
ApiAudio, ApiChat, ApiMessage, ApiPeer, ApiVoice,
|
|
MediaContent,
|
|
} from '../api/types';
|
|
|
|
import {
|
|
getAudioHasCover, getChatAvatarHash, getChatTitle, getMediaHash, getMessageContent, getPeerTitle,
|
|
} from '../global/helpers';
|
|
import { resizeImage, scaleImage } from '../util/imageResize';
|
|
import { buildMediaMetadata } from '../util/mediaSession';
|
|
import { AVATAR_FULL_DIMENSIONS } from '../components/common/helpers/mediaDimensions';
|
|
import useAsync from './useAsync';
|
|
import useMedia from './useMedia';
|
|
import useOldLang from './useOldLang';
|
|
|
|
import telegramLogoPath from '../assets/telegram-logo-filled.svg';
|
|
|
|
const LOGO_DIMENSIONS = { width: 200, height: 200 };
|
|
const MINIMAL_SIZE = 115; // spec says 100, but on Chrome 93 it's not showing
|
|
|
|
// TODO Add support for video in future
|
|
const useMessageMediaMetadata = (
|
|
message?: ApiMessage, sender?: ApiPeer, chat?: ApiChat,
|
|
): MediaMetadata | undefined => {
|
|
const lang = useOldLang();
|
|
|
|
const { audio, voice } = message ? getMessageContent(message) : {} satisfies MediaContent;
|
|
const title = audio ? (audio.title || audio.fileName) : voice ? 'Voice message' : '';
|
|
const artist = audio?.performer || (sender && getPeerTitle(lang, sender));
|
|
const album = (chat && getChatTitle(lang, chat)) || 'Telegram';
|
|
|
|
const audioCoverHash = (audio && getAudioHasCover(audio) && getMediaHash(audio, 'pictogram'));
|
|
const avatarHash = sender && getChatAvatarHash(sender, 'big');
|
|
const hash = (audio && audioCoverHash) || (voice && avatarHash);
|
|
const media = useMedia(hash);
|
|
|
|
const size = useMemo(() => {
|
|
return getCoverSize(audio, voice, media);
|
|
}, [audio, media, voice]);
|
|
const { result: url } = useAsync(() => (
|
|
makeGoodArtwork(media, size)
|
|
), [media, size], telegramLogoPath);
|
|
return useMemo(() => {
|
|
return buildMediaMetadata({
|
|
title,
|
|
artist,
|
|
album,
|
|
artwork: [{ src: url }],
|
|
});
|
|
}, [album, artist, title, url]);
|
|
};
|
|
|
|
function makeGoodArtwork(url?: string, size?: { width: number; height: number }): Promise<string> {
|
|
if (!url) return Promise.resolve(telegramLogoPath);
|
|
if (!size) return resizeImage(url, MINIMAL_SIZE, MINIMAL_SIZE);
|
|
const min = Math.min(size.width, size.height);
|
|
if (min < MINIMAL_SIZE) {
|
|
const ratio = MINIMAL_SIZE / min;
|
|
return scaleImage(url, ratio);
|
|
}
|
|
return Promise.resolve(url);
|
|
}
|
|
|
|
function getCoverSize(audio?: ApiAudio, voice?: ApiVoice, url?: string) {
|
|
if (!url) return LOGO_DIMENSIONS;
|
|
if (audio) {
|
|
if (!audio.thumbnailSizes?.length) return undefined;
|
|
const preferred = audio.thumbnailSizes.find((size) => size.type === 'm');
|
|
return preferred || audio.thumbnailSizes[0]; // Sometimes `m` is not present
|
|
}
|
|
|
|
if (voice) {
|
|
return AVATAR_FULL_DIMENSIONS;
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
export default useMessageMediaMetadata;
|