Something went wrong. Try again.
A stream.place VOD client inspired by icarly.com
Something went wrong. Try again.
2.5 kB · 85 lines
TSX
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586'use client';
import { useState } from 'react';import { VideoRecord } from '@/lib/types';
function formatDuration(ns: number): string { const totalSeconds = Math.floor(ns / 1_000_000_000); const hours = Math.floor(totalSeconds / 3600); const minutes = Math.floor((totalSeconds % 3600) / 60); const seconds = totalSeconds % 60;
if (hours > 0) { return `${hours}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; } return `${minutes}:${seconds.toString().padStart(2, '0')}`;}
const STREAM_DISPLAY_NAMES: Record<string, string> = { 'stream1.atmosphereconf.org': 'Stream 1', 'stream2.atmosphereconf.org': 'Stream 2', 'stream3.atmosphereconf.org': 'Stream 3',};
function getDisplayName(handle: string): string { if (STREAM_DISPLAY_NAMES[handle]) { return STREAM_DISPLAY_NAMES[handle]; } // If it's a full handle like "username.bsky.social", show just the username part if (handle.includes('.')) { return handle.split('.')[0]; } // If it's a DID, show shortened version (fallback) if (handle.startsWith('did:')) { const parts = handle.split(':'); const lastPart = parts[parts.length - 1]; return lastPart.slice(0, 12) + '...'; } return handle;}
interface VideoCardProps { video: { uri: string; value: VideoRecord; handle: string; };}
export default function VideoCard({ video }: VideoCardProps) { const [showHandle, setShowHandle] = useState(false); const id = video.uri.split('/').pop(); const displayName = getDisplayName(video.handle); // For hover, always show the full handle (not the DID) const fullHandle = video.handle.startsWith('did:') ? displayName : video.handle;
return ( <a href={`/watch?id=${id}`} style={{ textDecoration: 'none' }} onMouseEnter={() => setShowHandle(true)} onMouseLeave={() => setShowHandle(false)} > <div className="video-card"> <div className="video-thumbnail" style={{ background: 'url(/atmosphere-conf-thumb.png) center/cover no-repeat' }} > <div className="play-overlay">▶</div> <div className="duration-badge"> {formatDuration(video.value.duration)} </div> </div> <div className="video-info"> <h3 className="video-title">{video.value.title}</h3> <p className="video-creator"> {showHandle ? fullHandle : displayName} </p> </div> </div> </a> );}