42 lines
1.7 KiB
TypeScript
42 lines
1.7 KiB
TypeScript
import { Link, useLocation } from 'react-router-dom'
|
||
import type { FeedVideoDto } from '../api/client'
|
||
import { formatDuration, formatRelativeTime } from '../utils/format'
|
||
import DownloadButton from './DownloadButton'
|
||
import Icon from './Icon'
|
||
|
||
interface Props {
|
||
video: FeedVideoDto
|
||
}
|
||
|
||
function VideoCard({ video }: Props) {
|
||
const duration = formatDuration(video.duration_seconds)
|
||
const href = `/video/${video.youtube_video_id}`
|
||
const location = useLocation()
|
||
const from = location.pathname + location.search
|
||
const rememberScroll = () => sessionStorage.setItem(`feed-scroll:${from}`, String(window.scrollY))
|
||
|
||
return (
|
||
<li className="video-card">
|
||
<Link to={href} state={{ from }} onClick={rememberScroll} className="video-thumbnail" aria-label={`Смотреть: ${video.title}`}>
|
||
{video.thumbnail_url ? (
|
||
<img src={video.thumbnail_url} alt="" loading="lazy" />
|
||
) : (
|
||
<div className="video-thumbnail-placeholder" />
|
||
)}
|
||
{duration && <span className="duration-badge">{duration}</span>}
|
||
</Link>
|
||
<div className="video-info">
|
||
<Link to={href} state={{ from }} onClick={rememberScroll} className="video-title" title={video.title}>
|
||
{video.title}
|
||
</Link>
|
||
<div className="video-meta"><span className="video-channel">{video.channel.title}</span><span>{formatRelativeTime(video.published_at)}</span></div>
|
||
<div className="video-actions">
|
||
<Link to={href} state={{ from }} onClick={rememberScroll} className="button-link"><Icon name="play" size={16} /> Смотреть</Link>
|
||
<DownloadButton video={video} />
|
||
</div>
|
||
</div>
|
||
</li>
|
||
)
|
||
}
|
||
|
||
export default VideoCard
|