first commit
Some checks failed
Build / run (push) Has been cancelled

This commit is contained in:
maher
2025-10-29 11:42:25 +01:00
commit 703f50a09d
4595 changed files with 385164 additions and 0 deletions

View File

@@ -0,0 +1,113 @@
import {useTrans} from '@common/i18n/use-trans';
import {message} from '@common/i18n/message';
import clsx from 'clsx';
import {ImageSize, useImageSrc} from '@app/images/use-image-src';
import {Episode} from '@app/titles/models/episode';
import {EpisodeLink} from '@app/episodes/episode-link';
import {Title} from '@app/titles/models/title';
import {ReactNode} from 'react';
import {Link} from 'react-router-dom';
import {IconButton} from '@common/ui/buttons/icon-button';
import {getWatchLink} from '@app/videos/watch-page/get-watch-link';
import {MediaPlayIcon} from '@common/icons/media/media-play';
import {MovieIcon} from '@common/icons/material/Movie';
interface Props {
title: Title;
episode: Episode;
seasonNumber?: number;
className?: string;
size?: string;
lazy?: boolean;
srcSize?: ImageSize;
children?: ReactNode;
aspect?: string;
link?: string;
wrapWithLink?: boolean;
showPlayButton?: boolean;
rightAction?: ReactNode;
}
export function EpisodePoster({
episode,
title,
seasonNumber,
className,
size,
srcSize,
lazy = true,
children,
aspect = 'aspect-video',
link,
wrapWithLink = true,
showPlayButton,
rightAction,
}: Props) {
const {trans} = useTrans();
const src = useImageSrc(episode.poster, {size: srcSize});
const imageClassName = clsx(
'w-full h-full object-cover bg-fg-base/4',
!src ? 'flex items-center justify-center' : 'block',
);
let image = src ? (
<img
className={imageClassName}
draggable={false}
loading={lazy ? 'lazy' : 'eager'}
src={src}
alt={trans(message('Poster for :name', {values: {name: episode.name}}))}
/>
) : (
<span className={imageClassName}>
<MovieIcon className="max-w-[60%] text-divider" size="text-6xl" />
</span>
);
const playButton =
showPlayButton && episode.primary_video ? (
<IconButton
color="white"
variant="flat"
className="absolute bottom-12 left-12 z-10 shadow-md"
elementType={Link}
radius="rounded-full"
to={getWatchLink(episode.primary_video)}
>
<MediaPlayIcon />
</IconButton>
) : null;
if (wrapWithLink) {
image = link ? (
<Link to={link}>{image}</Link>
) : (
<EpisodeLink
title={title}
episode={episode}
seasonNumber={episode.season_number ?? seasonNumber}
displayContents
>
{image}
</EpisodeLink>
);
}
return (
<div
className={clsx('group relative flex-shrink-0', size, aspect, className)}
>
{image}
{playButton}
{children && <div className="absolute bottom-14 left-14">{children}</div>}
{wrapWithLink && (
<div className="pointer-events-none absolute inset-0 bg-black opacity-0 transition-opacity group-hover:opacity-10" />
)}
{rightAction && (
<div className="absolute bottom-12 right-12 z-10 shadow-md">
{rightAction}
</div>
)}
</div>
);
}