2024-07-10 22:11:18 +00:00
|
|
|
import { getUrl, getNextVod, getPreviousVod, getLocalizedDate } from '@/app/lib/vods';
|
|
|
|
import { IVod } from '@/app/lib/vods';
|
2024-01-20 16:16:14 +00:00
|
|
|
import Link from 'next/link';
|
|
|
|
import { VideoInteractive } from './video-interactive';
|
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
2024-03-29 07:28:02 +00:00
|
|
|
import { faChevronLeft, faChevronRight, faGlobe, faImage, faLink } from "@fortawesome/free-solid-svg-icons";
|
2024-01-20 16:16:14 +00:00
|
|
|
import { notFound } from 'next/navigation';
|
|
|
|
import { IpfsCid } from './ipfs-cid';
|
|
|
|
import LinkableHeading from './linkable-heading';
|
2024-06-13 02:54:44 +00:00
|
|
|
import Image from "next/legacy/image";
|
2024-03-29 07:28:02 +00:00
|
|
|
import Thumbnail from './thumbnail';
|
2024-01-20 16:16:14 +00:00
|
|
|
|
|
|
|
export function getVodTitle(vod: IVod): string {
|
2024-02-27 15:52:43 +00:00
|
|
|
// console.log('lets getVodTitle, ey?')
|
|
|
|
// console.log(JSON.stringify(vod, null, 2))
|
2025-01-11 03:10:04 +00:00
|
|
|
return vod.title || vod.announce_title || `VOD ${vod.id}`
|
|
|
|
// return vod.title || vod.announceTitle || (vod?.date2 && vod?.vtuber?.display_name) ? `${vod.vtuber.display_name} ${vod.date_2}` : `VOD ${vod.id}`;
|
2024-01-20 16:16:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export function buildMuxUrl(playbackId: string, token: string) {
|
|
|
|
return `https://stream.mux.com/${playbackId}.m3u8?token=${token}`
|
|
|
|
}
|
|
|
|
|
|
|
|
export function buildMuxSignedPlaybackId(playbackId: string, token: string) {
|
|
|
|
return `${playbackId}?token=${token}`
|
|
|
|
}
|
|
|
|
|
|
|
|
export function buildMuxThumbnailUrl(playbackId: string, token: string) {
|
|
|
|
return `https://image.mux.com/${playbackId}/storyboard.vtt?token=${token}`
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default async function VodPage({vod}: { vod: IVod }) {
|
|
|
|
|
|
|
|
if (!vod) notFound();
|
2025-01-11 03:10:04 +00:00
|
|
|
if (!vod.vtuber) {
|
|
|
|
throw new Error(`vod.vtuber was falsy.`)
|
|
|
|
}
|
|
|
|
const slug = vod.vtuber.slug;
|
2024-01-20 16:16:14 +00:00
|
|
|
const previousVod = await getPreviousVod(vod);
|
|
|
|
const nextVod = await getNextVod(vod);
|
|
|
|
|
2025-01-11 03:10:04 +00:00
|
|
|
// return <pre><code>{JSON.stringify(previousVod, null, 2)}</code></pre>
|
|
|
|
// return <p>{slug} VOD @todo previousVod={previousVod.title} nextVod={nextVod?.title}</p>
|
2024-01-20 16:16:14 +00:00
|
|
|
return (
|
|
|
|
|
|
|
|
<div className="container">
|
2024-03-30 06:26:26 +00:00
|
|
|
<div className="section pt-0">
|
|
|
|
<VideoInteractive vod={vod}></VideoInteractive>
|
2025-01-11 03:10:04 +00:00
|
|
|
{/* <pre><code>{JSON.stringify(vod, null, 2)}</code></pre> */}
|
2024-01-20 16:16:14 +00:00
|
|
|
|
2025-01-11 03:10:04 +00:00
|
|
|
{(vod.thumbnail) && (<div className='mb-5'>
|
2024-03-30 06:26:26 +00:00
|
|
|
<LinkableHeading text="Thumbnail Image" slug="thumb" icon={faImage}></LinkableHeading>
|
2025-01-11 03:10:04 +00:00
|
|
|
<Thumbnail url={vod.thumbnail.cdn_url}></Thumbnail>
|
2024-03-30 06:26:26 +00:00
|
|
|
</div>)}
|
2024-03-29 07:28:02 +00:00
|
|
|
|
2025-01-11 03:10:04 +00:00
|
|
|
{(vod.ipfs_cid) && (
|
2024-03-30 06:26:26 +00:00
|
|
|
<>
|
|
|
|
<LinkableHeading text="IPFS Content IDs" slug="ipfs" icon={faGlobe}></LinkableHeading>
|
2025-01-11 03:10:04 +00:00
|
|
|
{vod.ipfs_cid && (
|
|
|
|
<IpfsCid label="Source" cid={vod.ipfs_cid}></IpfsCid>
|
2024-03-30 06:26:26 +00:00
|
|
|
)}
|
|
|
|
</>
|
|
|
|
)}
|
2024-01-20 16:16:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
<nav className="level mt-5">
|
|
|
|
<div className='level-left'>
|
|
|
|
<div className='level-item'>
|
|
|
|
{!!previousVod && (
|
2025-01-11 03:10:04 +00:00
|
|
|
<Link className='button' href={getUrl(previousVod, slug, previousVod.date_2)}>
|
2024-01-20 16:16:14 +00:00
|
|
|
<FontAwesomeIcon
|
|
|
|
icon={faChevronLeft}
|
|
|
|
className='fas faChevronLeft'
|
|
|
|
></FontAwesomeIcon>
|
|
|
|
<span className="ml-2">Prev VOD {getLocalizedDate(previousVod)}</span>
|
|
|
|
</Link>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className='level-center'>
|
|
|
|
<div className='level-item'>
|
2025-01-11 03:10:04 +00:00
|
|
|
{/* <p className='has-text-grey-darker'>UUID {vod.uuid}</p> UUID is too long for this space! */}
|
|
|
|
<p className='has-text-grey-darker'>ID {vod.id}</p>
|
2024-01-20 16:16:14 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className='level-right'>
|
|
|
|
<div className='level-item'>
|
|
|
|
{!!nextVod && (
|
2025-01-11 03:10:04 +00:00
|
|
|
<Link className='button' href={getUrl(nextVod, slug, nextVod.date_2)}>
|
2024-01-20 16:16:14 +00:00
|
|
|
<span className="mr-2">Next VOD {getLocalizedDate(nextVod)}</span>
|
|
|
|
<FontAwesomeIcon
|
|
|
|
icon={faChevronRight}
|
|
|
|
className='fas faChevronRight'
|
|
|
|
></FontAwesomeIcon>
|
|
|
|
</Link>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|