Add new slug property for videos.

These will in the future hold pre-generated slugs since some runs can have the
same title and slugs are generated based on those titles.

This also implements a default for when no slugs are set (as is the case for all
videos right now) where the slug is still generated based on the title but a
counter suffix is added for dupe titles.
master
Icedream 2021-07-09 10:59:46 +02:00
parent 5781966b91
commit 40cbd2ed6e
Signed by: icedream
GPG Key ID: 1573F6D8EFE4D0CF
5 changed files with 31 additions and 7 deletions

View File

@ -89,6 +89,7 @@ class VideoList extends React.Component<VideoListProps, VideoListState> {
duration,
fileName,
title,
slug,
sourceVideoStart,
sourceVideoEnd,
},
@ -100,6 +101,7 @@ class VideoList extends React.Component<VideoListProps, VideoListState> {
id={id}
thumbnailServerURL={thumbnailServerURL}
fileName={fileName}
slug={slug}
title={title}
sourceVideoStart={sourceVideoStart}
sourceVideoEnd={sourceVideoEnd}

View File

@ -39,6 +39,7 @@ export default function VideoListItem({
duration,
id,
fileName,
slug,
title,
sourceVideoStart,
sourceVideoEnd,
@ -47,6 +48,7 @@ export default function VideoListItem({
duration: number | string,
id: string,
fileName: string,
slug: string,
title: string,
sourceVideoStart: number | string,
sourceVideoEnd: number | string,
@ -77,7 +79,6 @@ export default function VideoListItem({
}
displayDuration = videoEnd - videoStart;
}
const titleUrlSlug = sanitizeTitle(title);
const listGroupItem = (
<ListGroup.Item action>
<Media>
@ -131,7 +132,7 @@ export default function VideoListItem({
);
if (fileName) {
return (
<Link passHref href="/[id]/[vslug]" as={`/${id}/${titleUrlSlug}`}>
<Link passHref href="/[id]/[vslug]" as={`/${id}/${slug}`}>
{listGroupItem}
</Link>
);

View File

@ -115,7 +115,7 @@ const getProps = withSession(async (req, _res, { id, vslug }: VideoPlayerPagePar
redirect: true,
id,
video,
vslug: sanitizeTitle(video.title),
vslug: video.slug,
},
};
}
@ -132,13 +132,13 @@ const getProps = withSession(async (req, _res, { id, vslug }: VideoPlayerPagePar
redirect: true,
id,
video: realVIndex,
vslug: sanitizeTitle(video.title),
vslug: video.slug,
},
};
}
// Check if we can find any video with matching vslug
const video = videos.find(({ title }: { title: string }) => sanitizeTitle(title) === vslug);
const video = videos.find(({ slug }: VideoEntry) => slug === vslug);
if (!video) {
return { props: {} };
}

View File

@ -15,8 +15,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { VideoList } from './datatypes/VideoList';
import { VideoEntry, VideoList } from './datatypes/VideoList';
import { VideoOnDemandIndex } from './datatypes/VideoOnDemandIdentifier';
import sanitizeTitle from './sanitizeTitle';
const upstreamURL = process.env.UPSTREAM_URL;
const upstreamDirectURL = process.env.UPSTREAM_DIRECT_URL || upstreamURL;
@ -73,7 +74,26 @@ export async function getIndex(): Promise<VideoOnDemandIndex> {
}
export async function getVideos(id: string): Promise<VideoList> {
return getDirect(`videos/${id}.json`);
const result: VideoList = await getDirect(`videos/${id}.json`);
result.videos = result.videos.reduce((all: Array<VideoEntry>, {
slug,
title,
...video
}: VideoEntry) => [
...all,
{
...video,
title,
slug: typeof slug === 'string'
? slug
: sanitizeTitle(title + (
all.find(v => v.title === title)
? ` ${all.filter(v => v.title === title).length + 1}`
: ''
)),
},
], [])
return result;
}
export function getDownloadURL(id: string, fileName: string): string {

View File

@ -19,6 +19,7 @@ export interface VideoEntry {
fileName:string
title: string
duration?: number | string,
slug: string,
sourceVideoURL: string
sourceVideoStart: number | string
sourceVideoEnd: number | string