hello

+1 -2
live-embed/index.html
··· 2 2 <html lang="en"> 3 3 <head> 4 4 <meta charset="UTF-8" /> 5 - <link rel="icon" type="image/svg+xml" href="/vite.svg" /> 6 5 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 - <title>Vite + React + TS</title> 6 + <title>zero bluesky live-updating post rendering</title> 8 7 </head> 9 8 <body> 10 9 <div id="root"></div>
+5
live-embed/src/App.css
··· 14 14 display: flex; 15 15 flex-wrap: wrap; 16 16 gap: 1rem; 17 + justify-content: center; 18 + } 19 + 20 + .explain { 21 + text-align: left; 17 22 }
+18 -2
live-embed/src/App.tsx
··· 44 44 45 45 return ( 46 46 <> 47 - <h1>zero bluesky infra post rendering</h1> 48 - <p className="with">with live-updating interaction counts</p> 47 + <h1>zero bluesky infra post rendering (WIP)</h1> 48 + <p className="with">with real-time interaction count updates</p> 49 49 <div className="posts"> 50 50 {currentPair.map(p => ( 51 51 <Post key={p} atUri={p} updatedLinks={updates[p]} /> 52 52 ))} 53 53 </div> 54 + 55 + <div className="explain"> 56 + <h2>How does it work?</h2> 57 + <ul> 58 + <li><strong>Post content</strong>: fetches direct from PDS with <a href="https://github.com/mary-ext/atcute" target="_blank">atcute</a>.</li> 59 + <li><strong>Interaction counts</strong>: queries <a href="https://constellation.microcosm.blue/" target="_blank">constellation</a>.</li> 60 + <li><strong>Interaction updates</strong>: subscribes to <a href="https://spacedust.microcosm.blue/" target="_blank">spacedust</a>.</li> 61 + <li>There is no backend.</li> 62 + </ul> 63 + <p>The post selection takes a couple top posts from the public bluesky Discover feed so I guess it's kind of cheating but hey.</p> 64 + <p>Oh and media files load from Bluesky's CDN so that's also cheating.</p> 65 + 66 + <h2>If you actually want to embed a post</h2> 67 + <p>See <a href="https://mary-ext.codeberg.page/bluesky-embed/" target="_blank"><code>&lt;bluesky-embed&gt;</code></a> from <a href="https://mary.my.id" target="_blank">mary</a>. It's a very solid post renderer, unlike this demo.</p> 68 + </div> 69 + 54 70 </> 55 71 ) 56 72 }
+9
live-embed/src/Post.css
··· 1 1 .post { 2 2 background-color: rgb(32, 41, 53); 3 3 border: 1px solid rgb(46, 64, 82); 4 + border-radius: 0.1em; 4 5 display: flex; 6 + flex-basis: 20em; 5 7 flex-direction: column; 8 + min-width: 12em; 6 9 max-width: 24em; 7 10 } 8 11 ··· 31 34 .stat.like:before { 32 35 content: "♡ "; 33 36 } 37 + 38 + @media (prefers-color-scheme: light) { 39 + .post { 40 + background-color: rgb(241, 243, 245); 41 + } 42 + }
+1 -1
live-embed/src/constellation.ts
··· 16 16 ) { 17 17 const url = new URL('/links/all', endpoint); 18 18 url.searchParams.set('target', atUri); 19 - const res = await fetch(url); 19 + const res = await fetch(url, { signal: AbortSignal.timeout(4000) }); 20 20 if (!res.ok) throw new Error(res); 21 21 const { links } = await res.json(); 22 22
+4
live-embed/src/index.css
··· 36 36 margin: 0; 37 37 } 38 38 39 + h2 { 40 + margin-top: 2em; 41 + } 42 + 39 43 button { 40 44 border-radius: 8px; 41 45 border: 1px solid transparent;
+1
live-embed/src/samplePosts.ts
··· 28 28 let which: 'A' | 'B' = 'A'; 29 29 30 30 async function next() { 31 + console.info('[sample posts: next]'); 31 32 try { 32 33 const { feed } = await getFeed(); 33 34 if (dying) return;