A stream.place VOD client inspired by icarly.com
1
fork

Configure Feed

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

Reduce logo size, fix favicon, and properly resolve DIDs to handles

jack e2cc8e4f ffad166c

+14 -11
+1 -1
src/app/icarly.css
··· 131 131 } 132 132 133 133 .icarly-logo img { 134 - height: 100px; 134 + height: 60px; 135 135 width: auto; 136 136 object-fit: contain; 137 137 }
+2 -2
src/app/layout.tsx
··· 6 6 title: "iStream - Video on Demand", 7 7 description: "Watch videos from the stream.place community! The coolest VOD site inspired by iCarly.", 8 8 icons: { 9 - icon: "/iStream_Logo.png", 10 - shortcut: "/iStream_Logo.png", 9 + icon: "/favicon-32.png", 10 + shortcut: "/favicon-32.png", 11 11 apple: "/iStream_Logo.png", 12 12 }, 13 13 openGraph: {
+2 -2
src/components/HomeClient.tsx
··· 55 55 // Cache for resolved handles to avoid redundant requests 56 56 const handleCache = new Map<string, string>(); 57 57 58 - // Resolve handles with batching to avoid rate limits 58 + // Resolve handles using the correct AT Protocol endpoint 59 59 const resolveHandle = async (did: string): Promise<string> => { 60 60 // Check cache first 61 61 if (handleCache.has(did)) { ··· 65 65 try { 66 66 // Add delay to avoid rate limiting 67 67 await new Promise(resolve => setTimeout(resolve, 100)); 68 - const handleRes = await fetch(`https://public.api.bsky.app/xrpc/com.atproto.identity.resolveDid?did=${did}`); 68 + const handleRes = await fetch(`https://bsky.social/xrpc/com.atproto.repo.describeRepo?repo=${did}`); 69 69 70 70 if (!handleRes.ok) { 71 71 // Silently cache the DID itself if resolution fails
+9 -6
src/components/VideoCard.tsx
··· 25 25 if (STREAM_DISPLAY_NAMES[handle]) { 26 26 return STREAM_DISPLAY_NAMES[handle]; 27 27 } 28 - // If it's a DID, show shortened version 28 + // If it's a full handle like "username.bsky.social", show just the username part 29 + if (handle.includes('.')) { 30 + return handle.split('.')[0]; 31 + } 32 + // If it's a DID, show shortened version (fallback) 29 33 if (handle.startsWith('did:')) { 30 34 const parts = handle.split(':'); 31 35 const lastPart = parts[parts.length - 1]; 32 36 return lastPart.slice(0, 12) + '...'; 33 37 } 34 - // If it's a full handle like "username.bsky.social", show just the username part 35 - if (handle.includes('.')) { 36 - return handle.split('.')[0]; 37 - } 38 38 return handle; 39 39 } 40 40 ··· 50 50 const [showHandle, setShowHandle] = useState(false); 51 51 const id = video.uri.split('/').pop(); 52 52 const displayName = getDisplayName(video.handle); 53 + 54 + // For hover, always show the full handle (not the DID) 55 + const fullHandle = video.handle.startsWith('did:') ? displayName : video.handle; 53 56 54 57 return ( 55 58 <a ··· 73 76 <div className="video-info"> 74 77 <h3 className="video-title">{video.value.title}</h3> 75 78 <p className="video-creator"> 76 - {showHandle ? video.handle : displayName} 79 + {showHandle ? fullHandle : displayName} 77 80 </p> 78 81 </div> 79 82 </div>