gdq-archive/frontend/pages/[id].tsx

151 lines
3.7 KiB
TypeScript
Raw Normal View History

2020-08-22 20:25:57 +00:00
import * as React from 'react';
import { Breadcrumb } from 'react-bootstrap';
import Head from 'next/head';
import Link from 'next/link';
import { useIntl } from 'react-intl';
import { FormattedMessage } from '../components/localization';
import RelativeTime from '../components/RelativeTime';
import VideoList from '../components/VideoList';
import { notFound } from '../util/status';
import { getIndex, getVideos } from '../util/api';
import { VideoEntry } from '../util/datatypes/VideoList';
export async function getServerSideProps({ params: { id } }: { params: { id: string } }) {
// Fetch URL to thumbnails server
const {
ids,
servers: { thumbnails: thumbnailServerURL },
} = await getIndex();
const vodMeta = ids.find(({
id: thisID,
}: {
id: string
}) => id === thisID);
if (!vodMeta) {
return {
props: {},
};
}
const { title } = vodMeta;
// Fetch list of videos for this VOD ID
const vodInfo = await getVideos(id);
const { videos } = vodInfo;
let lastUpdatedAt = null;
lastUpdatedAt = vodInfo.lastUpdatedAt;
const finalVideos = videos
.map((video: VideoEntry) => ({
...video,
duration: typeof video.duration === 'string' ? parseFloat(video.duration) : video.duration || null,
sourceVideoStart: typeof video.sourceVideoStart === 'string' ? parseFloat(video.sourceVideoStart) : video.sourceVideoStart || null,
sourceVideoEnd: typeof video.sourceVideoEnd === 'string' ? parseFloat(video.sourceVideoEnd) : video.sourceVideoEnd || null,
}));
// Pass data to the page via props
return {
props: {
id,
thumbnailServerURL,
title,
videos: finalVideos,
lastUpdatedAt,
},
};
}
export default function VideoListPage({
id,
lastUpdatedAt,
thumbnailServerURL,
title,
videos,
}: {
id: string,
lastUpdatedAt: string,
thumbnailServerURL: string,
title: string,
videos: Array<VideoEntry>
}) {
if (!id) {
return notFound();
}
let lastUpdatedDate = null;
if (typeof (lastUpdatedAt) === 'string') {
lastUpdatedDate = new Date(lastUpdatedAt);
}
const intl = useIntl();
return (
<div>
<Head>
<title>
{title}
{' '}
{' '}
{intl.formatMessage({
id: 'App.title',
description: 'The full title of the website',
defaultMessage: 'Games Done Quick Instant Archive',
})}
</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<Breadcrumb>
<Link passHref href="/">
<Breadcrumb.Item>
<FormattedMessage
id="Breadcrumb.homeTitle"
defaultMessage="GDQ Instant Archive"
description="Root node text in breadcrumb"
/>
</Breadcrumb.Item>
</Link>
<Link passHref href="/[id]" as={`/${id}`}>
<Breadcrumb.Item active>
{title}
</Breadcrumb.Item>
</Link>
</Breadcrumb>
<VideoList
id={id}
thumbnailServerURL={thumbnailServerURL}
videos={videos}
/>
{
lastUpdatedDate
? (
<footer className="pt-4 my-md-5 pt-md-5 border-top">
2021-01-03 17:43:25 +00:00
<FormattedMessage
id="VideoListPage.updatedLastAgo"
description="Text below the video list on the video list page that says in relative time when the list was last updated"
defaultMessage="Updated last {time}"
values={{
time: (
<RelativeTime>
{lastUpdatedDate}
</RelativeTime>
),
}}
/>
2020-08-22 20:25:57 +00:00
</footer>
)
: ''
}
</div>
);
}