mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-01-24 03:05:13 +00:00
Use backdrop image as background for modal.
This commit is contained in:
parent
d917a3a915
commit
b19efd2f75
1 changed files with 230 additions and 203 deletions
|
|
@ -343,224 +343,251 @@ const VODModal = ({ vod, opened, onClose }) => {
|
|||
size="xl"
|
||||
centered
|
||||
>
|
||||
<Stack spacing="md">
|
||||
{loadingDetails && (
|
||||
<Group spacing="xs" mb={8}>
|
||||
<Loader size="xs" />
|
||||
<Text size="xs" color="dimmed">Loading additional details...</Text>
|
||||
</Group>
|
||||
)}
|
||||
|
||||
{/* Backdrop image if available */}
|
||||
<Box style={{ position: 'relative', minHeight: 400 }}>
|
||||
{/* Backdrop image as background */}
|
||||
{displayVOD.backdrop_path && displayVOD.backdrop_path.length > 0 && (
|
||||
<Box style={{ position: 'relative', height: 200, borderRadius: '8px', overflow: 'hidden' }}>
|
||||
<>
|
||||
<Image
|
||||
src={displayVOD.backdrop_path[0]}
|
||||
height={200}
|
||||
alt={`${displayVOD.name} backdrop`}
|
||||
fit="cover"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
objectFit: 'cover',
|
||||
zIndex: 0,
|
||||
borderRadius: 8,
|
||||
filter: 'blur(2px) brightness(0.5)'
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Movie poster and basic info */}
|
||||
<Flex gap="md">
|
||||
{/* Use movie_image or logo */}
|
||||
{(displayVOD.movie_image || displayVOD.logo?.url) ? (
|
||||
<Box style={{ flexShrink: 0 }}>
|
||||
<Image
|
||||
src={displayVOD.movie_image || displayVOD.logo.url}
|
||||
width={200}
|
||||
height={300}
|
||||
alt={displayVOD.name}
|
||||
fit="contain"
|
||||
style={{ borderRadius: '8px' }}
|
||||
/>
|
||||
</Box>
|
||||
) : (
|
||||
{/* Overlay for readability */}
|
||||
<Box
|
||||
style={{
|
||||
width: 200,
|
||||
height: 300,
|
||||
backgroundColor: '#404040',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
borderRadius: '8px',
|
||||
flexShrink: 0
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
background: 'linear-gradient(180deg, rgba(24,24,27,0.85) 60%, rgba(24,24,27,1) 100%)',
|
||||
zIndex: 1,
|
||||
borderRadius: 8
|
||||
}}
|
||||
>
|
||||
<Play size={48} color="#666" />
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Stack spacing="md" style={{ flex: 1 }}>
|
||||
<Title order={3}>{displayVOD.name}</Title>
|
||||
|
||||
{/* Original name if different */}
|
||||
{displayVOD.o_name && displayVOD.o_name !== displayVOD.name && (
|
||||
<Text size="sm" color="dimmed" style={{ fontStyle: 'italic' }}>
|
||||
Original: {displayVOD.o_name}
|
||||
</Text>
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{/* Modal content above backdrop */}
|
||||
<Box style={{ position: 'relative', zIndex: 2 }}>
|
||||
<Stack spacing="md">
|
||||
{loadingDetails && (
|
||||
<Group spacing="xs" mb={8}>
|
||||
<Loader size="xs" />
|
||||
<Text size="xs" color="dimmed">Loading additional details...</Text>
|
||||
</Group>
|
||||
)}
|
||||
|
||||
<Group spacing="md">
|
||||
{displayVOD.year && <Badge color="blue">{displayVOD.year}</Badge>}
|
||||
{displayVOD.duration && <Badge color="gray">{formatDuration(displayVOD.duration)}</Badge>}
|
||||
{displayVOD.rating && <Badge color="yellow">{displayVOD.rating}</Badge>}
|
||||
{displayVOD.age && <Badge color="orange">{displayVOD.age}</Badge>}
|
||||
<Badge color="green">Movie</Badge>
|
||||
</Group>
|
||||
|
||||
{/* Release date */}
|
||||
{displayVOD.release_date && (
|
||||
<Text size="sm" color="dimmed">
|
||||
<strong>Release Date:</strong> {displayVOD.release_date}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{displayVOD.genre && (
|
||||
<Text size="sm" color="dimmed">
|
||||
<strong>Genre:</strong> {displayVOD.genre}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{displayVOD.director && (
|
||||
<Text size="sm" color="dimmed">
|
||||
<strong>Director:</strong> {displayVOD.director}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{displayVOD.actors && (
|
||||
<Text size="sm" color="dimmed">
|
||||
<strong>Cast:</strong> {displayVOD.actors}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{displayVOD.country && (
|
||||
<Text size="sm" color="dimmed">
|
||||
<strong>Country:</strong> {displayVOD.country}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{/* Description */}
|
||||
{displayVOD.description && (
|
||||
<Box>
|
||||
<Text size="sm" weight={500} mb={8}>Description</Text>
|
||||
<Text size="sm">
|
||||
{displayVOD.description}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Watch Trailer button at top */}
|
||||
{displayVOD.youtube_trailer && (
|
||||
<Button
|
||||
component="a"
|
||||
href={displayVOD.youtube_trailer}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
variant="outline"
|
||||
color="red"
|
||||
style={{ marginTop: 'auto', alignSelf: 'flex-start' }}
|
||||
>
|
||||
Watch Trailer on YouTube
|
||||
</Button>
|
||||
)}
|
||||
{/* Removed Play Movie button from here */}
|
||||
</Stack>
|
||||
</Flex>
|
||||
{/* Provider Information & Play Button Row */}
|
||||
{(vod?.m3u_account || true) && (
|
||||
<Group spacing="md" align="center" mt="md">
|
||||
{vod?.m3u_account && (
|
||||
<Box>
|
||||
<Text size="sm" weight={500} mb={8}>IPTV Provider</Text>
|
||||
<Group spacing="md">
|
||||
<Badge color="blue" variant="light">
|
||||
{vod.m3u_account.name}
|
||||
</Badge>
|
||||
{vod.m3u_account.account_type && (
|
||||
<Badge color="gray" variant="outline" size="xs">
|
||||
{vod.m3u_account.account_type === 'XC' ? 'Xtream Codes' : 'Standard M3U'}
|
||||
</Badge>
|
||||
)}
|
||||
</Group>
|
||||
</Box>
|
||||
)}
|
||||
<Button
|
||||
leftSection={<Play size={16} />}
|
||||
variant="filled"
|
||||
color="blue"
|
||||
size="md"
|
||||
onClick={handlePlayVOD}
|
||||
style={{ alignSelf: 'flex-start' }}
|
||||
>
|
||||
Play Movie
|
||||
{vod?.m3u_account && (
|
||||
<span style={{ fontWeight: 400, fontSize: 12, marginLeft: 8 }}>
|
||||
{`(via ${vod.m3u_account.name}${displayVOD.bitrate ? `, ~${displayVOD.bitrate} kbps` : ''})`}
|
||||
</span>
|
||||
{/* Movie poster and basic info */}
|
||||
<Flex gap="md">
|
||||
{/* Use movie_image or logo */}
|
||||
{(displayVOD.movie_image || displayVOD.logo?.url) ? (
|
||||
<Box style={{ flexShrink: 0 }}>
|
||||
<Image
|
||||
src={displayVOD.movie_image || displayVOD.logo.url}
|
||||
width={200}
|
||||
height={300}
|
||||
alt={displayVOD.name}
|
||||
fit="contain"
|
||||
style={{ borderRadius: '8px' }}
|
||||
/>
|
||||
</Box>
|
||||
) : (
|
||||
<Box
|
||||
style={{
|
||||
width: 200,
|
||||
height: 300,
|
||||
backgroundColor: '#404040',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
borderRadius: '8px',
|
||||
flexShrink: 0
|
||||
}}
|
||||
>
|
||||
<Play size={48} color="#666" />
|
||||
</Box>
|
||||
)}
|
||||
</Button>
|
||||
</Group>
|
||||
)}
|
||||
{/* Technical Details */}
|
||||
{(displayVOD.bitrate || displayVOD.video || displayVOD.audio) && (
|
||||
<Stack spacing={4} mt="xs">
|
||||
<Text size="sm" weight={500}>Technical Details:</Text>
|
||||
{displayVOD.bitrate && displayVOD.bitrate > 0 && (
|
||||
<Text size="xs" color="dimmed">
|
||||
<strong>Bitrate:</strong> {displayVOD.bitrate} kbps
|
||||
</Text>
|
||||
|
||||
<Stack spacing="md" style={{ flex: 1 }}>
|
||||
<Title order={3}>{displayVOD.name}</Title>
|
||||
|
||||
{/* Original name if different */}
|
||||
{displayVOD.o_name && displayVOD.o_name !== displayVOD.name && (
|
||||
<Text size="sm" color="dimmed" style={{ fontStyle: 'italic' }}>
|
||||
Original: {displayVOD.o_name}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
<Group spacing="md">
|
||||
{displayVOD.year && <Badge color="blue">{displayVOD.year}</Badge>}
|
||||
{displayVOD.duration && <Badge color="gray">{formatDuration(displayVOD.duration)}</Badge>}
|
||||
{displayVOD.rating && <Badge color="yellow">{displayVOD.rating}</Badge>}
|
||||
{displayVOD.age && <Badge color="orange">{displayVOD.age}</Badge>}
|
||||
<Badge color="green">Movie</Badge>
|
||||
</Group>
|
||||
|
||||
{/* Release date */}
|
||||
{displayVOD.release_date && (
|
||||
<Text size="sm" color="dimmed">
|
||||
<strong>Release Date:</strong> {displayVOD.release_date}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{displayVOD.genre && (
|
||||
<Text size="sm" color="dimmed">
|
||||
<strong>Genre:</strong> {displayVOD.genre}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{displayVOD.director && (
|
||||
<Text size="sm" color="dimmed">
|
||||
<strong>Director:</strong> {displayVOD.director}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{displayVOD.actors && (
|
||||
<Text size="sm" color="dimmed">
|
||||
<strong>Cast:</strong> {displayVOD.actors}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{displayVOD.country && (
|
||||
<Text size="sm" color="dimmed">
|
||||
<strong>Country:</strong> {displayVOD.country}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{/* Description */}
|
||||
{displayVOD.description && (
|
||||
<Box>
|
||||
<Text size="sm" weight={500} mb={8}>Description</Text>
|
||||
<Text size="sm">
|
||||
{displayVOD.description}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Watch Trailer button at top */}
|
||||
{displayVOD.youtube_trailer && (
|
||||
<Button
|
||||
component="a"
|
||||
href={displayVOD.youtube_trailer}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
variant="outline"
|
||||
color="red"
|
||||
style={{ marginTop: 'auto', alignSelf: 'flex-start' }}
|
||||
>
|
||||
Watch Trailer on YouTube
|
||||
</Button>
|
||||
)}
|
||||
{/* Removed Play Movie button from here */}
|
||||
</Stack>
|
||||
</Flex>
|
||||
{/* Provider Information & Play Button Row */}
|
||||
{(vod?.m3u_account || true) && (
|
||||
<Group spacing="md" align="center" mt="md">
|
||||
{vod?.m3u_account && (
|
||||
<Box>
|
||||
<Text size="sm" weight={500} mb={8}>IPTV Provider</Text>
|
||||
<Group spacing="md">
|
||||
<Badge color="blue" variant="light">
|
||||
{vod.m3u_account.name}
|
||||
</Badge>
|
||||
{vod.m3u_account.account_type && (
|
||||
<Badge color="gray" variant="outline" size="xs">
|
||||
{vod.m3u_account.account_type === 'XC' ? 'Xtream Codes' : 'Standard M3U'}
|
||||
</Badge>
|
||||
)}
|
||||
</Group>
|
||||
</Box>
|
||||
)}
|
||||
<Button
|
||||
leftSection={<Play size={16} />}
|
||||
variant="filled"
|
||||
color="blue"
|
||||
size="md"
|
||||
onClick={handlePlayVOD}
|
||||
style={{ alignSelf: 'flex-start' }}
|
||||
>
|
||||
Play Movie
|
||||
{vod?.m3u_account && (
|
||||
<span style={{ fontWeight: 400, fontSize: 12, marginLeft: 8 }}>
|
||||
{`(via ${vod.m3u_account.name}${displayVOD.bitrate ? `, ~${displayVOD.bitrate} kbps` : ''})`}
|
||||
</span>
|
||||
)}
|
||||
</Button>
|
||||
</Group>
|
||||
)}
|
||||
{displayVOD.video && Object.keys(displayVOD.video).length > 0 && (
|
||||
<Text size="xs" color="dimmed">
|
||||
<strong>Video:</strong>{' '}
|
||||
{displayVOD.video.codec_long_name || displayVOD.video.codec_name}
|
||||
{displayVOD.video.profile ? ` (${displayVOD.video.profile})` : ''}
|
||||
{displayVOD.video.width && displayVOD.video.height
|
||||
? `, ${displayVOD.video.width}x${displayVOD.video.height}`
|
||||
: ''}
|
||||
{displayVOD.video.display_aspect_ratio
|
||||
? `, Aspect Ratio: ${displayVOD.video.display_aspect_ratio}`
|
||||
: ''}
|
||||
{displayVOD.video.bit_rate
|
||||
? `, Bitrate: ${Math.round(Number(displayVOD.video.bit_rate) / 1000)} kbps`
|
||||
: ''}
|
||||
{displayVOD.video.r_frame_rate
|
||||
? `, Frame Rate: ${displayVOD.video.r_frame_rate.replace('/', '/')} fps`
|
||||
: ''}
|
||||
{displayVOD.video.tags?.encoder
|
||||
? `, Encoder: ${displayVOD.video.tags.encoder}`
|
||||
: ''}
|
||||
</Text>
|
||||
)}
|
||||
{displayVOD.audio && Object.keys(displayVOD.audio).length > 0 && (
|
||||
<Text size="xs" color="dimmed">
|
||||
<strong>Audio:</strong>{' '}
|
||||
{displayVOD.audio.codec_long_name || displayVOD.audio.codec_name}
|
||||
{displayVOD.audio.profile ? ` (${displayVOD.audio.profile})` : ''}
|
||||
{displayVOD.audio.channel_layout
|
||||
? `, Channels: ${displayVOD.audio.channel_layout}`
|
||||
: displayVOD.audio.channels
|
||||
? `, Channels: ${displayVOD.audio.channels}`
|
||||
: ''}
|
||||
{displayVOD.audio.sample_rate
|
||||
? `, Sample Rate: ${displayVOD.audio.sample_rate} Hz`
|
||||
: ''}
|
||||
{displayVOD.audio.bit_rate
|
||||
? `, Bitrate: ${Math.round(Number(displayVOD.audio.bit_rate) / 1000)} kbps`
|
||||
: ''}
|
||||
{displayVOD.audio.tags?.handler_name
|
||||
? `, Handler: ${displayVOD.audio.tags.handler_name}`
|
||||
: ''}
|
||||
</Text>
|
||||
{/* Technical Details */}
|
||||
{(displayVOD.bitrate || displayVOD.video || displayVOD.audio) && (
|
||||
<Stack spacing={4} mt="xs">
|
||||
<Text size="sm" weight={500}>Technical Details:</Text>
|
||||
{displayVOD.bitrate && displayVOD.bitrate > 0 && (
|
||||
<Text size="xs" color="dimmed">
|
||||
<strong>Bitrate:</strong> {displayVOD.bitrate} kbps
|
||||
</Text>
|
||||
)}
|
||||
{displayVOD.video && Object.keys(displayVOD.video).length > 0 && (
|
||||
<Text size="xs" color="dimmed">
|
||||
<strong>Video:</strong>{' '}
|
||||
{displayVOD.video.codec_long_name || displayVOD.video.codec_name}
|
||||
{displayVOD.video.profile ? ` (${displayVOD.video.profile})` : ''}
|
||||
{displayVOD.video.width && displayVOD.video.height
|
||||
? `, ${displayVOD.video.width}x${displayVOD.video.height}`
|
||||
: ''}
|
||||
{displayVOD.video.display_aspect_ratio
|
||||
? `, Aspect Ratio: ${displayVOD.video.display_aspect_ratio}`
|
||||
: ''}
|
||||
{displayVOD.video.bit_rate
|
||||
? `, Bitrate: ${Math.round(Number(displayVOD.video.bit_rate) / 1000)} kbps`
|
||||
: ''}
|
||||
{displayVOD.video.r_frame_rate
|
||||
? `, Frame Rate: ${displayVOD.video.r_frame_rate.replace('/', '/')} fps`
|
||||
: ''}
|
||||
{displayVOD.video.tags?.encoder
|
||||
? `, Encoder: ${displayVOD.video.tags.encoder}`
|
||||
: ''}
|
||||
</Text>
|
||||
)}
|
||||
{displayVOD.audio && Object.keys(displayVOD.audio).length > 0 && (
|
||||
<Text size="xs" color="dimmed">
|
||||
<strong>Audio:</strong>{' '}
|
||||
{displayVOD.audio.codec_long_name || displayVOD.audio.codec_name}
|
||||
{displayVOD.audio.profile ? ` (${displayVOD.audio.profile})` : ''}
|
||||
{displayVOD.audio.channel_layout
|
||||
? `, Channels: ${displayVOD.audio.channel_layout}`
|
||||
: displayVOD.audio.channels
|
||||
? `, Channels: ${displayVOD.audio.channels}`
|
||||
: ''}
|
||||
{displayVOD.audio.sample_rate
|
||||
? `, Sample Rate: ${displayVOD.audio.sample_rate} Hz`
|
||||
: ''}
|
||||
{displayVOD.audio.bit_rate
|
||||
? `, Bitrate: ${Math.round(Number(displayVOD.audio.bit_rate) / 1000)} kbps`
|
||||
: ''}
|
||||
{displayVOD.audio.tags?.handler_name
|
||||
? `, Handler: ${displayVOD.audio.tags.handler_name}`
|
||||
: ''}
|
||||
</Text>
|
||||
)}
|
||||
</Stack>
|
||||
)}
|
||||
{/* YouTube trailer if available */}
|
||||
</Stack>
|
||||
)}
|
||||
{/* YouTube trailer if available */}
|
||||
</Stack>
|
||||
</Box>
|
||||
</Box>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue