demos for spacedust

fix double-count (thanks ollie) + constellation

+49 -13
+7 -11
live-embed/src/App.tsx
··· 19 19 setCurrentPair(updatedPair); 20 20 spacedust.setSubjects(updatedPair); 21 21 setUpdates(current => { // cleanup, probably should combine with pair directly 22 - console.log('hi??'); 23 22 const next = {}; 24 23 updatedPair.forEach(uri => next[uri] = current[uri] ?? {}); 25 24 return next; ··· 27 26 }); 28 27 29 28 function handleLink({ subject, source }) { 30 - console.log('i only run once', source, subject); 31 - 32 - setUpdates(current => { 33 - console.log('i run twice??', source, subject); 34 - const next = Object.assign({}, current); 35 - if (!next[subject][source]) next[subject][source] = 0; 36 - next[subject][source] += 1; 37 - return next; 38 - }); 29 + setUpdates(current => ({ 30 + ...current, 31 + [subject]: { 32 + ...current[subject], 33 + [source]: (current[subject][source] ?? 0) + 1 34 + }, 35 + })); 39 36 } 40 37 41 38 return () => { 42 - console.log('byeeee'); 43 39 cancelRotation(); 44 40 spacedust.close(); 45 41 iMightBeAZombie = true;
+42 -2
live-embed/src/Post.tsx
··· 1 - const nameSource = source => ({ 1 + import { useEffect, useState } from 'react'; 2 + 3 + const nicerSource = source => ({ 2 4 'app.bsky.feed.like:subject.uri': 'like', // likes 3 5 'app.bsky.feed.repost:subject.uri': 'repost', // reposts 4 6 'app.bsky.feed.post:embed.record.uri': 'quote', // normal quotes ··· 7 9 }[source]); 8 10 9 11 export function Post({ atUri, updatedLinks }) { 12 + const [baseStats, setBaseStats] = useState({}); 13 + 10 14 const nicerStats = {}; 15 + 16 + for (const [collection, paths] of Object.entries(baseStats)) { 17 + for (const [oldStylePath, counts] of Object.entries(paths)) { 18 + const newStylePath = `${collection}:${oldStylePath.slice(1)}`; 19 + const name = nicerSource(newStylePath); 20 + if (!name) continue; // perils of constellation's (soon-deprecated) /all 21 + if (name === 'like') { 22 + nicerStats[name] = counts.distinct_dids; 23 + } else { 24 + nicerStats[name] = counts.records; 25 + } 26 + } 27 + } 28 + 11 29 for (const [key, val] of Object.entries(updatedLinks)) { 12 - const name = nameSource(key); 30 + const name = nicerSource(key); 13 31 if (!nicerStats[name]) nicerStats[name] = 0; 14 32 nicerStats[name] += val; 15 33 } 34 + 35 + useEffect(() => { 36 + let cancel = false; 37 + 38 + (async () => { 39 + try { 40 + const url = new URL('/links/all', 'https://constellation.microcosm.blue'); 41 + url.searchParams.set('target', atUri); 42 + const res = await fetch(url); 43 + if (!res.ok) throw new Error(res); 44 + const { links } = await res.json(); 45 + setBaseStats(links); 46 + } catch (e) { 47 + console.warn('fetching base stats failed', e); 48 + } 49 + })(); 50 + 51 + return () => cancel = true; 52 + }, [atUri]); 53 + 54 + useState() 55 + 16 56 17 57 return ( 18 58 <div>