viewcontent fix
This commit is contained in:
parent
3b31c4e6cb
commit
61b50df864
|
|
@ -52,9 +52,22 @@ export const ViewContentPage = () => {
|
||||||
}
|
}
|
||||||
}, [statusState]);
|
}, [statusState]);
|
||||||
|
|
||||||
|
const haveLicense = useMemo(() => (
|
||||||
|
content?.data?.have_licenses?.includes('listen') ||
|
||||||
|
content?.data?.have_licenses?.includes('resale')
|
||||||
|
), [content]);
|
||||||
|
|
||||||
|
const contentMime = content?.data?.content_mime ?? null;
|
||||||
|
const contentKind = content?.data?.display_options?.content_kind ?? null;
|
||||||
const mediaUrl = content?.data?.display_options?.content_url ?? null;
|
const mediaUrl = content?.data?.display_options?.content_url ?? null;
|
||||||
const isAudio = Boolean(content?.data?.content_type?.startsWith('audio'));
|
const isAudio = contentKind === 'audio' || Boolean(content?.data?.content_type?.startsWith('audio'));
|
||||||
const isReady = Boolean(mediaUrl);
|
const isVideo = contentKind === 'video' || Boolean(content?.data?.content_type?.startsWith('video'));
|
||||||
|
const isBinary = contentKind === 'binary' || (!isAudio && !isVideo);
|
||||||
|
const hasInlinePlayer = Boolean(mediaUrl) && (isAudio || isVideo);
|
||||||
|
const binaryDownloadReady = Boolean(mediaUrl) && isBinary;
|
||||||
|
const isReadyState = statusState === "ready";
|
||||||
|
const previewAvailable = Boolean(content?.data?.display_options?.has_preview);
|
||||||
|
const coverImage = content?.data?.display_options?.metadata?.image ?? null;
|
||||||
const metadataName = content?.data?.display_options?.metadata?.name;
|
const metadataName = content?.data?.display_options?.metadata?.name;
|
||||||
const contentTitle = metadataName || content?.data?.encrypted?.title || 'Контент';
|
const contentTitle = metadataName || content?.data?.encrypted?.title || 'Контент';
|
||||||
const processingDetails = useMemo(() => {
|
const processingDetails = useMemo(() => {
|
||||||
|
|
@ -67,6 +80,10 @@ export const ViewContentPage = () => {
|
||||||
};
|
};
|
||||||
}, [conversionState, statusMessage, uploadState]);
|
}, [conversionState, statusMessage, uploadState]);
|
||||||
|
|
||||||
|
const canDownload = Boolean(mediaUrl) && haveLicense && ((content?.data?.downloadable ?? false) || isBinary);
|
||||||
|
const binaryAwaitingAccess = isBinary && !binaryDownloadReady;
|
||||||
|
const isFailed = statusState === "failed";
|
||||||
|
|
||||||
const handleBuyContentTON = useCallback(async () => {
|
const handleBuyContentTON = useCallback(async () => {
|
||||||
if (!contentId) {
|
if (!contentId) {
|
||||||
console.error('No content identifier available for purchase');
|
console.error('No content identifier available for purchase');
|
||||||
|
|
@ -185,11 +202,6 @@ export const ViewContentPage = () => {
|
||||||
}
|
}
|
||||||
}, [content, refetchContent]);
|
}, [content, refetchContent]);
|
||||||
|
|
||||||
const haveLicense = useMemo(() => (
|
|
||||||
content?.data?.have_licenses?.includes('listen') ||
|
|
||||||
content?.data?.have_licenses?.includes('resale')
|
|
||||||
), [content]);
|
|
||||||
|
|
||||||
const hadLicenseRef = useRef<boolean>(haveLicense);
|
const hadLicenseRef = useRef<boolean>(haveLicense);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -230,11 +242,15 @@ export const ViewContentPage = () => {
|
||||||
const handleDwnldContent = async () => {
|
const handleDwnldContent = async () => {
|
||||||
try {
|
try {
|
||||||
const fileUrl = content?.data?.display_options?.content_url;
|
const fileUrl = content?.data?.display_options?.content_url;
|
||||||
|
if (!fileUrl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const fileName = content?.data?.display_options?.metadata?.name || 'content';
|
const fileName = content?.data?.display_options?.metadata?.name || 'content';
|
||||||
const fileFormat = content?.data?.content_ext || '.raw';
|
const rawExt = content?.data?.content_ext ?? 'bin';
|
||||||
|
const normalizedExt = rawExt.replace(/^\.+/, '');
|
||||||
await WebApp.downloadFile({
|
await WebApp.downloadFile({
|
||||||
url: fileUrl,
|
url: fileUrl,
|
||||||
file_name: fileName + '.' + fileFormat,
|
file_name: `${fileName}.${normalizedExt}`,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error downloading content:', error);
|
console.error('Error downloading content:', error);
|
||||||
|
|
@ -242,40 +258,56 @@ export const ViewContentPage = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className={'min-h-screen flex w-full flex-col gap-[50px] px-4 '}>
|
<main className={'min-h-screen flex w-full flex-col gap-[40px] px-4 '}>
|
||||||
{isCongratsModal && <CongratsModal onConfirm={handleConfirmCongrats} />}
|
{isCongratsModal && <CongratsModal onConfirm={handleConfirmCongrats} />}
|
||||||
{isErrorModal && <ErrorModal onConfirm={handleErrorModal} />}
|
{isErrorModal && <ErrorModal onConfirm={handleErrorModal} />}
|
||||||
{isReady && isAudio &&
|
{coverImage && (
|
||||||
content?.data?.display_options?.metadata?.image && (
|
<div className="mt-[30px] flex w-full justify-center">
|
||||||
<div className={'mt-[30px] h-[314px] w-full'}>
|
<div className="relative aspect-square w-full max-w-[320px] rounded-3xl border border-slate-900/60 bg-transparent">
|
||||||
<img
|
<div className="absolute inset-0 flex items-center justify-center overflow-hidden">
|
||||||
alt={'content_image'}
|
<img
|
||||||
className={'h-full w-full object-cover object-center'}
|
alt={'content cover'}
|
||||||
src={content?.data?.display_options?.metadata?.image}
|
className={'max-h-full max-w-full object-contain'}
|
||||||
/>
|
src={coverImage}
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{isReady ? (
|
{isReadyState ? (
|
||||||
<>
|
<>
|
||||||
{isAudio ? (
|
{hasInlinePlayer && (
|
||||||
<AudioPlayer src={mediaUrl ?? ''} />
|
isAudio ? (
|
||||||
) : (
|
<AudioPlayer src={mediaUrl ?? ''} />
|
||||||
<ReactPlayer
|
) : (
|
||||||
playsinline={true}
|
<ReactPlayer
|
||||||
controls={true}
|
playsinline={true}
|
||||||
width="100%"
|
controls={true}
|
||||||
config={{
|
width="100%"
|
||||||
file: {
|
config={{
|
||||||
attributes: {
|
file: {
|
||||||
playsInline: true,
|
attributes: {
|
||||||
autoPlay: true,
|
playsInline: true,
|
||||||
poster: content?.data?.display_options?.metadata?.image || undefined,
|
autoPlay: true,
|
||||||
|
poster: content?.data?.display_options?.metadata?.image || undefined,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
}}
|
url={mediaUrl ?? ''}
|
||||||
url={mediaUrl}
|
light={coverImage || undefined}
|
||||||
/>
|
/>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
|
||||||
|
{binaryDownloadReady && (
|
||||||
|
<div className="rounded-2xl border border-slate-800 bg-slate-950/70 px-6 py-5 shadow-inner shadow-black/20">
|
||||||
|
<h2 className="text-base font-semibold text-slate-100">Файл готов к скачиванию</h2>
|
||||||
|
<p className="mt-2 text-sm text-slate-300">
|
||||||
|
{contentMime ? `Тип файла: ${contentMime}` : 'Скачайте оригинальные данные на устройство.'}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<section className={'flex flex-col'}>
|
<section className={'flex flex-col'}>
|
||||||
|
|
@ -285,26 +317,40 @@ export const ViewContentPage = () => {
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
{binaryAwaitingAccess && (
|
||||||
|
<div className="rounded-2xl border border-slate-800 bg-slate-950/70 px-6 py-5 text-sm text-slate-300">
|
||||||
|
<h2 className="text-base font-semibold text-slate-100">Предпросмотр недоступен</h2>
|
||||||
|
<p className="mt-2">
|
||||||
|
Этот файл нельзя открыть в браузере. Получите доступ, чтобы скачать оригинал на устройство.
|
||||||
|
</p>
|
||||||
|
{!previewAvailable && (
|
||||||
|
<p className="mt-2 text-xs text-slate-500">
|
||||||
|
Предпросмотр не формируется для бинарных данных.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="mt-auto pb-2">
|
<div className="mt-auto pb-2">
|
||||||
{content?.data?.downloadable && (
|
{canDownload && (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => handleDwnldContent()}
|
onClick={() => handleDwnldContent()}
|
||||||
className={'h-[48px] mb-4'}
|
className={'h-[48px] mb-4'}
|
||||||
label={`Скачать контент`}
|
label={`Скачать ${isBinary ? 'файл' : 'контент'}`}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!haveLicense && (
|
{!haveLicense && (
|
||||||
<div className="flex flex-row gap-4">
|
<div className="flex gap-4 pb-2">
|
||||||
<Button
|
<Button
|
||||||
onClick={handleBuyContentTON}
|
onClick={handleBuyContentTON}
|
||||||
className={'mb-4 h-[48px] px-2'}
|
className={'mb-4 h-[48px] px-2 flex-1 min-w-[140px] w-auto'}
|
||||||
label={`Купить за ${fromNanoTON(content?.data?.encrypted?.license?.resale?.price)} ТОН`}
|
label={`Купить за ${fromNanoTON(content?.data?.encrypted?.license?.resale?.price)} ТОН`}
|
||||||
includeArrows={content?.data?.invoice ? false : true}
|
includeArrows={content?.data?.invoice ? false : true}
|
||||||
/>
|
/>
|
||||||
{content?.data?.invoice && (
|
{content?.data?.invoice && (
|
||||||
<Button
|
<Button
|
||||||
onClick={handleBuyContentStars}
|
onClick={handleBuyContentStars}
|
||||||
className={'mb-4 h-[48px] px-2'}
|
className={'mb-4 h-[48px] px-2 flex-1 min-w-[140px] w-auto'}
|
||||||
label={`Купить за ${content?.data?.invoice?.amount} ⭐️`}
|
label={`Купить за ${content?.data?.invoice?.amount} ⭐️`}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
@ -332,10 +378,12 @@ export const ViewContentPage = () => {
|
||||||
<div className="flex flex-1 flex-col items-center justify-center py-16">
|
<div className="flex flex-1 flex-col items-center justify-center py-16">
|
||||||
<div className="max-w-md rounded-2xl border border-slate-800 bg-slate-950/70 px-6 py-8 text-center shadow-lg shadow-black/30">
|
<div className="max-w-md rounded-2xl border border-slate-800 bg-slate-950/70 px-6 py-8 text-center shadow-lg shadow-black/30">
|
||||||
<h1 className="text-lg font-semibold text-slate-100">
|
<h1 className="text-lg font-semibold text-slate-100">
|
||||||
Контент скоро будет здесь
|
{isFailed ? 'Не удалось подготовить контент' : 'Контент скоро будет здесь'}
|
||||||
</h1>
|
</h1>
|
||||||
<p className="mt-3 text-sm text-slate-300">
|
<p className="mt-3 text-sm text-slate-300">
|
||||||
Мы уже обрабатываем загруженный файл и обновим страницу автоматически, как только появится доступ к полному контенту.
|
{isFailed
|
||||||
|
? 'При обработке файла произошла ошибка. Попробуйте обновить страницу или повторно загрузить контент.'
|
||||||
|
: 'Мы уже обрабатываем загруженный файл и обновим страницу автоматически, как только появится доступ к полному контенту.'}
|
||||||
</p>
|
</p>
|
||||||
{statusMessage && (
|
{statusMessage && (
|
||||||
<p className="mt-4 text-[12px] text-slate-500">
|
<p className="mt-4 text-[12px] text-slate-500">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue