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
parent
5781966b91
commit
40cbd2ed6e
|
@ -89,6 +89,7 @@ class VideoList extends React.Component<VideoListProps, VideoListState> {
|
||||||
duration,
|
duration,
|
||||||
fileName,
|
fileName,
|
||||||
title,
|
title,
|
||||||
|
slug,
|
||||||
sourceVideoStart,
|
sourceVideoStart,
|
||||||
sourceVideoEnd,
|
sourceVideoEnd,
|
||||||
},
|
},
|
||||||
|
@ -100,6 +101,7 @@ class VideoList extends React.Component<VideoListProps, VideoListState> {
|
||||||
id={id}
|
id={id}
|
||||||
thumbnailServerURL={thumbnailServerURL}
|
thumbnailServerURL={thumbnailServerURL}
|
||||||
fileName={fileName}
|
fileName={fileName}
|
||||||
|
slug={slug}
|
||||||
title={title}
|
title={title}
|
||||||
sourceVideoStart={sourceVideoStart}
|
sourceVideoStart={sourceVideoStart}
|
||||||
sourceVideoEnd={sourceVideoEnd}
|
sourceVideoEnd={sourceVideoEnd}
|
||||||
|
|
|
@ -39,6 +39,7 @@ export default function VideoListItem({
|
||||||
duration,
|
duration,
|
||||||
id,
|
id,
|
||||||
fileName,
|
fileName,
|
||||||
|
slug,
|
||||||
title,
|
title,
|
||||||
sourceVideoStart,
|
sourceVideoStart,
|
||||||
sourceVideoEnd,
|
sourceVideoEnd,
|
||||||
|
@ -47,6 +48,7 @@ export default function VideoListItem({
|
||||||
duration: number | string,
|
duration: number | string,
|
||||||
id: string,
|
id: string,
|
||||||
fileName: string,
|
fileName: string,
|
||||||
|
slug: string,
|
||||||
title: string,
|
title: string,
|
||||||
sourceVideoStart: number | string,
|
sourceVideoStart: number | string,
|
||||||
sourceVideoEnd: number | string,
|
sourceVideoEnd: number | string,
|
||||||
|
@ -77,7 +79,6 @@ export default function VideoListItem({
|
||||||
}
|
}
|
||||||
displayDuration = videoEnd - videoStart;
|
displayDuration = videoEnd - videoStart;
|
||||||
}
|
}
|
||||||
const titleUrlSlug = sanitizeTitle(title);
|
|
||||||
const listGroupItem = (
|
const listGroupItem = (
|
||||||
<ListGroup.Item action>
|
<ListGroup.Item action>
|
||||||
<Media>
|
<Media>
|
||||||
|
@ -131,7 +132,7 @@ export default function VideoListItem({
|
||||||
);
|
);
|
||||||
if (fileName) {
|
if (fileName) {
|
||||||
return (
|
return (
|
||||||
<Link passHref href="/[id]/[vslug]" as={`/${id}/${titleUrlSlug}`}>
|
<Link passHref href="/[id]/[vslug]" as={`/${id}/${slug}`}>
|
||||||
{listGroupItem}
|
{listGroupItem}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
|
|
|
@ -115,7 +115,7 @@ const getProps = withSession(async (req, _res, { id, vslug }: VideoPlayerPagePar
|
||||||
redirect: true,
|
redirect: true,
|
||||||
id,
|
id,
|
||||||
video,
|
video,
|
||||||
vslug: sanitizeTitle(video.title),
|
vslug: video.slug,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -132,13 +132,13 @@ const getProps = withSession(async (req, _res, { id, vslug }: VideoPlayerPagePar
|
||||||
redirect: true,
|
redirect: true,
|
||||||
id,
|
id,
|
||||||
video: realVIndex,
|
video: realVIndex,
|
||||||
vslug: sanitizeTitle(video.title),
|
vslug: video.slug,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we can find any video with matching vslug
|
// 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) {
|
if (!video) {
|
||||||
return { props: {} };
|
return { props: {} };
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,9 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* 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 { VideoOnDemandIndex } from './datatypes/VideoOnDemandIdentifier';
|
||||||
|
import sanitizeTitle from './sanitizeTitle';
|
||||||
|
|
||||||
const upstreamURL = process.env.UPSTREAM_URL;
|
const upstreamURL = process.env.UPSTREAM_URL;
|
||||||
const upstreamDirectURL = process.env.UPSTREAM_DIRECT_URL || upstreamURL;
|
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> {
|
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 {
|
export function getDownloadURL(id: string, fileName: string): string {
|
||||||
|
|
|
@ -19,6 +19,7 @@ export interface VideoEntry {
|
||||||
fileName:string
|
fileName:string
|
||||||
title: string
|
title: string
|
||||||
duration?: number | string,
|
duration?: number | string,
|
||||||
|
slug: string,
|
||||||
sourceVideoURL: string
|
sourceVideoURL: string
|
||||||
sourceVideoStart: number | string
|
sourceVideoStart: number | string
|
||||||
sourceVideoEnd: number | string
|
sourceVideoEnd: number | string
|
||||||
|
|
Loading…
Reference in New Issue