vod jam and earl vod.atverkackt.de
4
fork

Configure Feed

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

Rename things, delete spec

+31 -73
+8 -8
README.md
··· 1 - # vod frog 1 + # vod jam 2 2 3 - vod frog, frog with the vods, i take the frogs on the vod. i vod on the frogs. 3 + vod jam, jam with the vods. 4 4 5 5 svelte app, fair amount of claude code work was done here but i've looked through it and most of it seems reasonable. please submit pull requests for anything sus!! 6 6 ··· 30 30 │ ├── WavyCircle.svelte # Circular wavy border for avatars 31 31 │ ├── MeshBackground.svelte # Layered SVG radial gradient background 32 32 │ ├── PlantOverlay.svelte # Fern leaves photo overlay with multiply blend 33 - │ ├── ToejamHeader.svelte # Header with ToeJam & Earl illustration 34 - │ ├── VideoCard.svelte # Video thumbnail card with scrub preview and hopping frog 35 - │ └── VideoPlayer.svelte # Custom HLS video player with frog scrub bar and frogeye fullscreen 33 + │ ├── VodjamHeader.svelte # Header with ToeJam & Earl illustration 34 + │ ├── VideoCard.svelte # Video thumbnail card with scrub preview and hopping vodjam sprite 35 + │ └── VideoPlayer.svelte # Custom HLS video player with vodjam scrub bar and ship fullscreen 36 36 ├── routes/ 37 37 │ ├── +layout.svelte # Global layout: fonts, cursor, background, plants 38 38 │ ├── +layout.ts # SPA mode config ··· 42 42 │ └── +page.ts # Profile route config 43 43 ├── static/ 44 44 │ ├── fonts/ # Bundled PicNic and Fang webfonts 45 - │ ├── froggie.png # Header frog illustration 46 - │ ├── froggiestand.png # Frog scrub sprite (standing) 47 - │ ├── froggiejump.png # Frog scrub sprite (jumping) 45 + │ ├── froggie.png # Header vodjam illustration 46 + │ ├── froggiestand.png # Vodjam scrub sprite (standing) 47 + │ ├── froggiejump.png # Vodjam scrub sprite (jumping) 48 48 │ ├── frogeye.png # Fullscreen toggle button 49 49 │ ├── frogcursor-small.png # Custom cursor 50 50 │ ├── frogicon.png # Favicon
assets.afphoto~lock~

This is a binary file and will not be displayed.

opengraph.afphoto~lock~

This is a binary file and will not be displayed.

-42
spec/designdoc.md
··· 1 - # Vod Frog Design Document 2 - 3 - ## What is Vod frog? 4 - 5 - Vod frog is an experimental frog / swamp themed player for vods created from @stream.place, a decentralized video streaming and hosting service built on the AT Protocol. Its purpose is to create a whimsical and exciting place for users to view videos from their favorite creators, a space that is reminiscent of a late 90s / early 2000s website with lots of small custom media and a bespoke layout that doesn't conform to the norms of modern web design. At the same time, we want it to be technically modern, so we try to procedurally generate as much of the page as possible to avoid drawing hundreds of custom assets. 6 - 7 - ## Vod frog color scheme 8 - 9 - Vod frog will use a vibrant color scheme consisting largely of greens and blues, with pinks and oranges used as accent colors, we will avoid using true white and black in favor of tints to give the page a more realistic feeling. 10 - 11 - The main colors will be: 12 - 13 - - 39FF44 - main vibrant green 14 - - 3992FF - darker water blue 15 - - FFA639 - orange accent color 16 - - FF3992 - pink accent color 17 - - FFDEED - light pink for use in dark regions 18 - - 0A182B - dark blue for use in most other areas, looks better on green 19 - 20 - ## Typography 21 - 22 - We will be using the system font PicNic for our more avant-garde header text, and the font Fang for the non-wiggly text for main video captions and things that need to be read at smaller sizes. s 23 - 24 - ## Overall Page design elements 25 - 26 - The main layout of the page will be a fairly traditional grid layout, with each element offset somewhat in a position determined by its DID and a tiny rotation to create an organic off-grid feeling. The borders of each box will be svgs that have random turbulent edges seeded by the RID of the records themselves so even records within one person's repository are randomly shifted and to avoid repetition. The cursor will be a custom frog drawing we provide in this folder, and on web there will be plant overlays on the sides of the page that enhance the sense of depth. 27 - 28 - The background of the page will be a mesh gradient that ranges from the full vibrant green to various desaturated versions and pools of blue in the corners. 29 - 30 - The video cards should use the svg wavy borders on both the outside and on top of the video thumbnail as a mask, giving the content the sense of being inset inside the page by using an inner shadow. 31 - 32 - ## References 33 - 34 - There are two main references for visuals provided. Both are not meant as perfect 100% fidelity mockups, but should be followed as closely as possible. 35 - 36 - ## Design Guidelines 37 - 38 - Use as few external dependencies as possible, ensuring they are lightweight and fast if needed. Split code into logical units, breaking it into multiple files based on logical structures and components. Avoid falling back into common visual patterns, keep things interesting and exploratory. 39 - 40 - ## Performance Considerations 41 - 42 - Build a comprehensive test suite that checks load times, ensures the titles of videos are presented in the right order in the right place. Build some scripts that test video streams and record bandwidth issues, codecs and other information, see how many fps we can stream.
spec/frogcursor.png

This is a binary file and will not be displayed.

spec/frogeye.png

This is a binary file and will not be displayed.

spec/froggie.png

This is a binary file and will not be displayed.

spec/froggiejump.png

This is a binary file and will not be displayed.

spec/froggiestand.png

This is a binary file and will not be displayed.

spec/frogicon.png

This is a binary file and will not be displayed.

spec/laptopmockup.png

This is a binary file and will not be displayed.

spec/mobilemockup.png

This is a binary file and will not be displayed.

spec/opengraph.png

This is a binary file and will not be displayed.

+7 -7
src/lib/ToejamHeader.svelte src/lib/VodjamHeader.svelte
··· 9 9 } 10 10 </script> 11 11 12 - <header class="toejam-header"> 12 + <header class="vodjam-header"> 13 13 <div class="title-area"> 14 14 <a href="/" class="logo-link" onclick={handleClick}><img src="/vod-jam.png" alt="VoD Jam" class="logo-img" /></a> 15 - <img src="/toe-jam-earl.png" alt="ToeJam & Earl" class="header-toejam" /> 15 + <img src="/toe-jam-earl.png" alt="ToeJam & Earl" class="header-vodjam" /> 16 16 </div> 17 17 <div class="subtitle-lines"> 18 18 <p class="subtitle">an exploration by</p> ··· 21 21 </header> 22 22 23 23 <style> 24 - .toejam-header { 24 + .vodjam-header { 25 25 padding: 30px 20px 50px; 26 26 position: relative; 27 27 } ··· 44 44 display: block; 45 45 } 46 46 47 - .header-toejam { 47 + .header-vodjam { 48 48 position: absolute; 49 49 right: -60px; 50 50 bottom: -30px; ··· 56 56 transition: transform 0.3s ease; 57 57 } 58 58 59 - .header-toejam:hover { 59 + .header-vodjam:hover { 60 60 transform: rotate(5deg) scale(1.1); 61 61 } 62 62 ··· 97 97 } 98 98 99 99 @media (max-width: 600px) { 100 - .toejam-header { 100 + .vodjam-header { 101 101 padding: 20px 16px 8px; 102 102 } 103 103 104 - .header-toejam { 104 + .header-vodjam { 105 105 right: -40px; 106 106 bottom: -20px; 107 107 }
+1 -1
src/lib/VideoCard.svelte
··· 6 6 - Thumbnail loaded from the creator's PDS via livestream record 7 7 - Hover scrub preview: creates a hidden <video> element, seeks it on mousemove, 8 8 and draws frames to a canvas overlaid on the thumbnail 9 - - Hopping toejam sprite follows the scrub position 9 + - Hopping vodjam sprite follows the scrub position 10 10 - Creator name links to their profile page 11 11 - Card position is jittered (rotation + translate) seeded by the creator DID 12 12 -->
+5 -5
src/lib/VideoPlayer.svelte
··· 96 96 ); 97 97 }); 98 98 99 - let lastHopProgress = 0; // Track progress to trigger toejam hops at intervals 99 + let lastHopProgress = 0; // Track progress to trigger vodjam hops at intervals 100 100 101 - /** Sync scrub position with playback, and animate the toejam hopping */ 101 + /** Sync scrub position with playback, and animate the vodjam hopping */ 102 102 function onTimeUpdate() { 103 103 if (!videoEl || isScrubbing) return; 104 104 currentTime = videoEl.currentTime; ··· 182 182 window.addEventListener("mouseup", onScrubUp); 183 183 } 184 184 185 - /** Start scrubbing by grabbing the toejam sprite directly */ 186 - function onToejamDown(e: MouseEvent) { 185 + /** Start scrubbing by grabbing the vodjam sprite directly */ 186 + function onVodjamDown(e: MouseEvent) { 187 187 e.preventDefault(); 188 188 e.stopPropagation(); 189 189 isScrubbing = true; ··· 282 282 <div 283 283 class="scrub-earl" 284 284 style="left: {scrubProgress * 100}%;" 285 - onmousedown={onToejamDown} 285 + onmousedown={onVodjamDown} 286 286 > 287 287 <img 288 288 src={`/earl-walk-${earlDirection}-${earlFrame}.png`}
+2 -2
src/routes/+page.svelte
··· 12 12 } from "$lib/api"; 13 13 import VideoPlayer from "$lib/VideoPlayer.svelte"; 14 14 import VideoCard from "$lib/VideoCard.svelte"; 15 - import ToejamHeader from "$lib/ToejamHeader.svelte"; 15 + import VodjamHeader from "$lib/VodjamHeader.svelte"; 16 16 import WavyBorder from "$lib/WavyBorder.svelte"; 17 17 import WavyCircle from "$lib/WavyCircle.svelte"; 18 18 import SpriteTime from "$lib/SpriteTime.svelte"; ··· 122 122 </svelte:head> 123 123 124 124 <div class="app"> 125 - <ToejamHeader onHomeClick={closePlayer} /> 125 + <VodjamHeader onHomeClick={closePlayer} /> 126 126 127 127 {#if selectedVideo} 128 128 <section class="player-section">
+4 -4
src/routes/profile/[handle]/+page.svelte
··· 3 3 import { page } from '$app/stores'; 4 4 import { getProfile, type BskyProfile } from '$lib/api'; 5 5 import WavyBorder from '$lib/WavyBorder.svelte'; 6 - import ToejamHeader from '$lib/ToejamHeader.svelte'; 6 + import VodjamHeader from '$lib/VodjamHeader.svelte'; 7 7 8 8 let profile: BskyProfile | null = $state(null); 9 9 let loading = $state(true); ··· 28 28 </svelte:head> 29 29 30 30 <div class="profile-page"> 31 - <ToejamHeader /> 31 + <VodjamHeader /> 32 32 33 33 {#if loading} 34 34 <div class="loading"> 35 - <img src="/earl-walk-right-1.png" alt="loading" class="loading-toejam" /> 35 + <img src="/earl-walk-right-1.png" alt="loading" class="loading-vodjam" /> 36 36 <p class="loading-text">hopping over to fetch profile...</p> 37 37 </div> 38 38 {:else if error} ··· 112 112 padding: 60px 20px; 113 113 } 114 114 115 - .loading-toejam { 115 + .loading-vodjam { 116 116 width: 64px; 117 117 height: auto; 118 118 animation: hop 0.6s ease-in-out infinite alternate;
+2 -2
tests/load-test.ts
··· 1 1 /** 2 - * VodFrog Load & Content Test Suite 2 + * VodJam Load & Content Test Suite 3 3 * 4 4 * Tests that the page loads within acceptable time limits, 5 5 * video titles are rendered in the correct order and positions, ··· 120 120 } 121 121 122 122 async function main() { 123 - console.log('🐸 VodFrog Test Suite\n'); 123 + console.log('🎮 VodJam Test Suite\n'); 124 124 125 125 const data = await testApiLoadTime(); 126 126 if (!data) {
+2 -2
tests/stream-test.ts
··· 1 1 /** 2 - * VodFrog Stream Diagnostics 2 + * VodJam Stream Diagnostics 3 3 * 4 4 * Tests video stream availability, records bandwidth estimates, 5 5 * checks codecs, and measures initial load performance. ··· 86 86 } 87 87 88 88 async function main() { 89 - console.log('🐸 VodFrog Stream Diagnostics\n'); 89 + console.log('🎮 VodJam Stream Diagnostics\n'); 90 90 91 91 const records = await fetchVideoRecords(6); 92 92 console.log(`Analyzing ${records.length} streams...\n`);