Skip to content
Open
167 changes: 87 additions & 80 deletions packages/web/app/components/beta-videos/beta-videos.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,57 @@

import React, { useState } from 'react';
import { Card, Row, Col, Typography, Empty, Modal } from 'antd';
import { InstagramOutlined, UserOutlined } from '@ant-design/icons';
import { InstagramOutlined, PlayCircleOutlined } from '@ant-design/icons';
import { BetaLink } from '@/app/lib/api-wrappers/sync-api-types';
import { themeTokens } from '@/app/theme/theme-config';

const { Title, Text } = Typography;
const { Title } = Typography;

interface ThumbnailProps {
betaLink: BetaLink;
}

const BetaThumbnail: React.FC<ThumbnailProps> = ({ betaLink }) => {
const [hasError, setHasError] = useState(false);

// If no thumbnail or it failed to load, show placeholder
if (!betaLink.thumbnail || hasError) {
return (
<div
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
background: `linear-gradient(135deg, ${themeTokens.neutral[200]} 0%, ${themeTokens.neutral[100]} 100%)`,
}}
>
<PlayCircleOutlined style={{ fontSize: 28, color: themeTokens.neutral[400] }} />
</div>
);
}

return (
<img
src={betaLink.thumbnail}
alt={`Beta by ${betaLink.foreign_username || 'unknown'}`}
onError={() => setHasError(true)}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
objectFit: 'cover',
}}
/>
);
};

interface BetaVideosProps {
betaLinks: BetaLink[];
Expand Down Expand Up @@ -51,91 +97,52 @@ const BetaVideos: React.FC<BetaVideosProps> = ({ betaLinks }) => {
{betaLinks.length === 0 ? (
<Empty description="No beta videos available" image={Empty.PRESENTED_IMAGE_SIMPLE} />
) : (
<Row gutter={[12, 12]}>
{betaLinks.map((betaLink, index) => {
const embedUrl = getInstagramEmbedUrl(betaLink.link);

return (
<Col xs={24} key={index}>
<Card
hoverable
size="small"
styles={{ body: { padding: 0 } }}
onClick={() => handleVideoClick(betaLink)}
<Row gutter={[8, 8]}>
{betaLinks.map((betaLink, index) => (
<Col xs={8} sm={6} md={8} lg={6} key={index}>
<Card
hoverable
size="small"
styles={{ body: { padding: 0 } }}
onClick={() => handleVideoClick(betaLink)}
>
<div
style={{
position: 'relative',
paddingBottom: '100%',
overflow: 'hidden',
borderRadius: themeTokens.borderRadius.md,
background: themeTokens.neutral[100],
}}
>
{embedUrl ? (
<BetaThumbnail betaLink={betaLink} />
{(betaLink.foreign_username || betaLink.angle) && (
<div
style={{
position: 'relative',
paddingBottom: '100%',
overflow: 'hidden',
borderRadius: `${themeTokens.borderRadius.md}px ${themeTokens.borderRadius.md}px 0 0`,
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
padding: `${themeTokens.spacing[1]}px ${themeTokens.spacing[2]}px`,
background: 'linear-gradient(transparent, rgba(0,0,0,0.7))',
color: 'white',
fontSize: themeTokens.typography.fontSize.xs,
}}
>
<iframe
src={embedUrl}
style={{
position: 'absolute',
top: '-20%',
left: 0,
width: '100%',
height: '140%',
border: 'none',
pointerEvents: 'none',
}}
scrolling="no"
title={`Beta video ${index + 1} thumbnail`}
/>
</div>
) : (
<div
style={{
padding: themeTokens.spacing[8],
textAlign: 'center',
background: themeTokens.neutral[100],
}}
>
<InstagramOutlined style={{ fontSize: 32, color: themeTokens.neutral[400] }} />
<p style={{ margin: `${themeTokens.spacing[2]}px 0 0`, color: themeTokens.neutral[500] }}>
Unable to load video
</p>
{betaLink.foreign_username && (
<span>@{betaLink.foreign_username}</span>
)}
{betaLink.angle && (
<span style={{ marginLeft: betaLink.foreign_username ? 4 : 0 }}>
{betaLink.angle}°
</span>
)}
</div>
)}
<div
style={{
padding: themeTokens.spacing[3],
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
borderTop: `1px solid ${themeTokens.neutral[100]}`,
}}
>
{betaLink.foreign_username && (
<Text type="secondary" style={{ fontSize: themeTokens.typography.fontSize.sm }}>
<UserOutlined style={{ marginRight: 4 }} />@{betaLink.foreign_username}
{betaLink.angle && <span style={{ marginLeft: 8 }}>{betaLink.angle}°</span>}
</Text>
)}
<a
href={betaLink.link}
target="_blank"
rel="noopener noreferrer"
onClick={(e) => e.stopPropagation()}
style={{
color: themeTokens.colors.primary,
fontSize: themeTokens.typography.fontSize.sm,
display: 'flex',
alignItems: 'center',
gap: 4,
}}
>
<InstagramOutlined /> View
</a>
</div>
</Card>
</Col>
);
})}
</div>
</Card>
</Col>
))}
</Row>
)}

Expand Down