vod frog, frog with the vods
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix warnings: remove unused CSS, use $derived for reactive props, clean up

goose.art 276e8e94 ad896131

+9 -30
+5 -6
src/lib/VideoCard.svelte
··· 27 27 let { video, onSelect }: { video: VideoRecord; onSelect: (video: VideoRecord) => void } = 28 28 $props(); 29 29 30 - let creatorHandle = $state(video.value.creator); 30 + let creatorHandle = $state(''); 31 31 let thumbnailUrl: string | null = $state(null); 32 32 33 33 // Extract rkey from URI for seeding 34 - const rkey = video.uri.split('/').pop() || video.uri; 35 - const offsets = getCardOffsets(video.value.creator); 36 - const cardStyle = `transform: rotate(${offsets.rotation}deg) translate(${offsets.translateX}px, ${offsets.translateY}px);`; 34 + const rkey = $derived(video.uri.split('/').pop() || video.uri); 35 + const offsets = $derived(getCardOffsets(video.value.creator)); 36 + const cardStyle = $derived(`transform: rotate(${offsets.rotation}deg) translate(${offsets.translateX}px, ${offsets.translateY}px);`); 37 37 38 38 // Scrub preview state — an offscreen video element is created on hover 39 39 // and seeked as the user moves their mouse across the thumbnail ··· 52 52 let pendingSeek: number | null = null; // Queued seek time if we're already seeking 53 53 54 54 onMount(() => { 55 + creatorHandle = video.value.creator; 55 56 resolveHandle(video.value.creator).then((h) => (creatorHandle = h)); 56 57 getThumbnailUrl(video).then((url) => (thumbnailUrl = url)); 57 58 }); ··· 252 253 object-fit: cover; 253 254 transition: opacity 0.15s; 254 255 } 255 - .thumb-img.hidden { opacity: 0; } 256 - 257 256 .scrub-canvas { 258 257 position: absolute; 259 258 inset: 0;
+3 -3
src/lib/WavyBorder.svelte
··· 18 18 children: any; 19 19 } = $props(); 20 20 21 - const paddingValue = typeof padding === 'number' ? `${padding}px` : padding; 21 + const paddingValue = $derived(typeof padding === 'number' ? `${padding}px` : padding); 22 22 23 - const { pts, svgPath } = generateWavyShape(seed); 23 + const { pts, svgPath } = $derived(generateWavyShape(seed)); 24 24 25 25 // Convert the points to a CSS polygon for clipping 26 - const clipPolygon = `polygon(${pts.map(([x, y]) => `${x.toFixed(2)}% ${y.toFixed(2)}%`).join(', ')})`; 26 + const clipPolygon = $derived(`polygon(${pts.map(([x, y]) => `${x.toFixed(2)}% ${y.toFixed(2)}%`).join(', ')})`); 27 27 28 28 /** 29 29 * Generate the wavy shape for this border.
+1 -1
src/lib/WavyCircle.svelte
··· 14 14 children: any; 15 15 } = $props(); 16 16 17 - const { svgPath, clipPolygon } = generateWavyCircle(seed); 17 + const { svgPath, clipPolygon } = $derived(generateWavyCircle(seed)); 18 18 19 19 function generateWavyCircle(s: string): { svgPath: string; clipPolygon: string } { 20 20 const cx = 50, cy = 50;
-20
src/routes/+page.svelte
··· 236 236 opacity: 0.4; 237 237 } 238 238 239 - .close-btn { 240 - background: #0a182b; 241 - color: #39ff44; 242 - border: 2px solid #39ff44; 243 - border-radius: 50%; 244 - width: 36px; 245 - height: 36px; 246 - font-size: 1rem; 247 - cursor: pointer; 248 - flex-shrink: 0; 249 - font-family: "Fang", system-ui, sans-serif; 250 - transition: 251 - background 0.15s, 252 - color 0.15s; 253 - } 254 239 255 - .close-btn:hover { 256 - background: #ff3992; 257 - border-color: #ff3992; 258 - color: #ffdeed; 259 - } 260 240 261 241 .grid { 262 242 display: grid;