feat: Add video embedding for YouTube and Vimeo links in PostCard.

This commit is contained in:
Christopher
2026-01-22 18:40:26 -08:00
parent 72d148066e
commit 59ba9f7d8b
3 changed files with 76 additions and 0 deletions
+19
View File
@@ -338,6 +338,25 @@ a.btn-primary:visited {
display: block; display: block;
} }
.video-embed-container {
position: relative;
padding-bottom: 56.25%; /* 16:9 aspect ratio */
height: 0;
overflow: hidden;
border-radius: var(--radius-md);
margin-bottom: 12px;
border: 1px solid var(--border);
background: #000;
}
.video-embed-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.post-actions { .post-actions {
display: flex; display: flex;
gap: 24px; gap: 24px;
+5
View File
@@ -5,6 +5,7 @@ import Link from 'next/link';
import { HeartIcon, RepeatIcon, MessageIcon, FlagIcon, TrashIcon } from '@/components/Icons'; import { HeartIcon, RepeatIcon, MessageIcon, FlagIcon, TrashIcon } from '@/components/Icons';
import { Post } from '@/lib/types'; import { Post } from '@/lib/types';
import { useAuth } from '@/lib/contexts/AuthContext'; import { useAuth } from '@/lib/contexts/AuthContext';
import { VideoEmbed } from '@/components/VideoEmbed';
interface PostCardProps { interface PostCardProps {
post: Post; post: Post;
@@ -181,6 +182,10 @@ export function PostCard({ post, onLike, onRepost, onComment, onDelete, isDetail
)} )}
{post.linkPreviewUrl && ( {post.linkPreviewUrl && (
<VideoEmbed url={post.linkPreviewUrl} />
)}
{post.linkPreviewUrl && !post.linkPreviewUrl.match(/(youtube\.com|youtu\.be|vimeo\.com)/) && (
<a <a
href={post.linkPreviewUrl} href={post.linkPreviewUrl}
target="_blank" target="_blank"
+52
View File
@@ -0,0 +1,52 @@
'use client';
interface VideoEmbedProps {
url: string;
}
export function VideoEmbed({ url }: VideoEmbedProps) {
const getYouTubeId = (url: string) => {
const regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
const match = url.match(regExp);
return (match && match[2].length === 11) ? match[2] : null;
};
const getVimeoId = (url: string) => {
const regExp = /(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/(?:[^\/]*)\/videos\/|album\/(?:\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)/;
const match = url.match(regExp);
return match ? match[1] : null;
};
const youtubeId = getYouTubeId(url);
const vimeoId = getVimeoId(url);
if (youtubeId) {
return (
<div className="video-embed-container">
<iframe
src={`https://www.youtube.com/embed/${youtubeId}`}
title="YouTube video player"
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
></iframe>
</div>
);
}
if (vimeoId) {
return (
<div className="video-embed-container">
<iframe
src={`https://player.vimeo.com/video/${vimeoId}`}
title="Vimeo video player"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture"
allowFullScreen
></iframe>
</div>
);
}
return null;
}