142 lines
3.9 KiB
TypeScript
142 lines
3.9 KiB
TypeScript
/**
|
|
* Copyright (C) 2019-2021 Carl Kittelberger <icedream@icedream.pw>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import React from 'react';
|
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
|
|
import ListGroup from 'react-bootstrap/ListGroup';
|
|
import Media from 'react-bootstrap/Media';
|
|
import Image from 'react-bootstrap/Image';
|
|
|
|
import Link from 'next/link';
|
|
|
|
import { getThumbnailURL } from '../util';
|
|
|
|
import FormattedDuration from './localization/FormattedDuration';
|
|
|
|
import style from './VideoListItem.module.scss';
|
|
import sanitizeTitle from '../util/sanitizeTitle';
|
|
|
|
import hourglassImage from '../images/hourglass.svg';
|
|
|
|
export default function VideoListItem({
|
|
thumbnailServerURL,
|
|
duration,
|
|
id,
|
|
fileName,
|
|
slug,
|
|
title,
|
|
sourceVideoStart,
|
|
sourceVideoEnd,
|
|
}: {
|
|
thumbnailServerURL: string,
|
|
duration: number | string,
|
|
id: string,
|
|
fileName: string,
|
|
slug: string,
|
|
title: string,
|
|
sourceVideoStart: number | string,
|
|
sourceVideoEnd: number | string,
|
|
}) {
|
|
let displayDuration = null;
|
|
if (duration !== null) {
|
|
if (typeof duration === 'string') {
|
|
displayDuration = parseFloat(duration);
|
|
} else {
|
|
displayDuration = duration;
|
|
}
|
|
} else if (
|
|
sourceVideoStart !== null
|
|
&& sourceVideoEnd !== null
|
|
&& sourceVideoStart !== sourceVideoEnd
|
|
) {
|
|
let videoEnd: number;
|
|
if (typeof sourceVideoEnd === 'string') {
|
|
videoEnd = parseFloat(sourceVideoEnd);
|
|
} else {
|
|
videoEnd = sourceVideoEnd;
|
|
}
|
|
let videoStart: number;
|
|
if (typeof sourceVideoStart === 'string') {
|
|
videoStart = parseFloat(sourceVideoStart);
|
|
} else {
|
|
videoStart = sourceVideoStart;
|
|
}
|
|
displayDuration = videoEnd - videoStart;
|
|
}
|
|
const listGroupItem = (
|
|
<ListGroup.Item action>
|
|
<Media>
|
|
<Image
|
|
className={['mr-3', style.thumbnail].join(' ')}
|
|
src={
|
|
fileName
|
|
? getThumbnailURL(thumbnailServerURL, id, fileName, 90 * 1000, {
|
|
width: 96,
|
|
})
|
|
: hourglassImage
|
|
}
|
|
srcSet={[96, 96 * 2, 96 * 3]
|
|
.map((width) => [
|
|
fileName
|
|
? getThumbnailURL(thumbnailServerURL, id, fileName, 90 * 1000, {
|
|
width,
|
|
})
|
|
: hourglassImage,
|
|
`${width}w`,
|
|
])
|
|
.map((item) => item.join(' '))
|
|
.join(', ')}
|
|
alt={title}
|
|
/>
|
|
<Media.Body>
|
|
<h5 className="mt-0 mb-3">{title}</h5>
|
|
<p>
|
|
{!fileName ? (
|
|
<span>
|
|
<FontAwesomeIcon icon="hourglass" />
|
|
{' '}
|
|
Coming up
|
|
</span>
|
|
) : ''}
|
|
{displayDuration !== null ? (
|
|
<span>
|
|
<FontAwesomeIcon icon="clock" />
|
|
{' '}
|
|
<FormattedDuration
|
|
seconds={displayDuration}
|
|
format="{hours} {minutes} {seconds}"
|
|
unitDisplay="short"
|
|
/>
|
|
</span>
|
|
) : ''}
|
|
</p>
|
|
</Media.Body>
|
|
</Media>
|
|
</ListGroup.Item>
|
|
);
|
|
if (fileName) {
|
|
return (
|
|
<Link passHref href="/[id]/[vslug]" as={`/${id}/${slug}`}>
|
|
{listGroupItem}
|
|
</Link>
|
|
);
|
|
}
|
|
return listGroupItem;
|
|
}
|