3.4 KiB
3.4 KiB
Media Viewer Page
Overview
File Path: admin/src/pages/public/MediaViewerPage.tsx (306 lines)
Route: /media/:id
Role Requirements: Public access (locked videos require login)
Purpose: Individual video player page with metadata, reactions, comments, and related videos.
Key Features:
- Back button to gallery
- VideoPlayer component with time tracking
- Metadata display (views, upvotes, category, quality tags)
- Upvote button (toggleable, session-based)
- ReactionButtons component (6 emojis)
- CommentSection component
- Related videos grid (3 cards)
- Locked video modal (redirect to login)
Features
1. Video Player
<VideoPlayer
videoUrl={video.videoUrl}
onTimeUpdate={(currentTime) => {
// Track view progress
if (currentTime > lastTrackedTime + 30) {
trackView(video.id, currentTime);
setLastTrackedTime(currentTime);
}
}}
/>
2. Metadata Display
<Space size={16}>
<Text type="secondary">
<EyeOutlined /> {video.viewCount} views
</Text>
<Text type="secondary">
<LikeOutlined /> {video.upvotes} upvotes
</Text>
<Tag color="blue">{video.category}</Tag>
{video.quality && <Tag color="green">{video.quality}p</Tag>}
</Space>
3. Upvote Button
<Button
type={hasUpvoted ? 'primary' : 'default'}
icon={hasUpvoted ? <LikeFilled /> : <LikeOutlined />}
onClick={handleUpvote}
size="large"
>
Upvote ({video.upvotes})
</Button>
4. Reaction Buttons
6 emoji reactions:
- 👍 Like
- ❤️ Love
- 😂 Haha
- 😮 Wow
- 😢 Sad
- 😡 Angry
<ReactionButtons
videoId={video.id}
reactions={video.reactions}
onReact={handleReact}
/>
5. Comment Section
<CommentSection
videoId={video.id}
comments={comments}
onSubmit={handleCommentSubmit}
/>
6. Related Videos
<Title level={4}>Related Videos</Title>
<Row gutter={[16, 16]}>
{relatedVideos.slice(0, 3).map(video => (
<Col xs={24} sm={8} key={video.id}>
<PublicVideoCard video={video} />
</Col>
))}
</Row>
7. Locked Video Handling
{video.isLocked && !user && (
<Modal
title="Login Required"
open={true}
footer={
<Button type="primary" onClick={() => navigate('/login')}>
Go to Login
</Button>
}
>
This video requires login to view.
</Modal>
)}
API Integration
Endpoints
1. Get Video
GET /api/media/public/:id
2. Track View
POST /api/media/public/:id/view
Content-Type: application/json
{
"currentTime": 67.5
}
3. Toggle Upvote
POST /api/media/public/:id/upvote
4. Add Reaction
POST /api/media/public/:id/react
Content-Type: application/json
{
"reactionType": "love"
}
Performance Considerations
- View Tracking: Throttled to 30-second intervals
- Related Videos: Limited to 3 (prevents over-fetching)
- Lazy Comments: Loaded separately after video metadata
- Video Preload:
preload="metadata"for faster initial render
Accessibility
- Keyboard Controls: Native video player controls
- Captions: Support for WebVTT subtitle files
- Screen Reader: All buttons have aria-labels
- Focus Management: Reaction buttons keyboard navigable