interactive intro to open social at-me.zzstoatzz.io

more accessible #7

merged opened by zzstoatzz.io targeting main from show-ownership

include links and such

Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:xbtmt2zjwlrfegqvch7fboei/sh.tangled.repo.pull/3m2rmnn25bb22
+157 -54
Diff #0
+88 -20
src/templates.rs
··· 9 9 10 10 11 11 12 + <meta property="og:type" content="website"> 13 + <meta property="og:url" content="https://at-me.fly.dev/"> 14 + <meta property="og:title" content="@me - explore your atproto identity"> 15 + <meta property="og:description" content="visualize your decentralized identity and see what apps have stored data in your Personal Data Server"> 16 + <meta property="og:image" content="https://at-me.fly.dev/static/og-image.png"> 12 17 18 + <!-- Twitter --> 19 + <meta property="twitter:card" content="summary_large_image"> 20 + <meta property="twitter:url" content="https://at-me.fly.dev/"> 21 + <meta property="twitter:title" content="@me - explore your atproto identity"> 22 + <meta property="twitter:description" content="visualize your decentralized identity and see what apps have stored data in your Personal Data Server"> 23 + <meta property="twitter:image" content="https://at-me.fly.dev/static/og-image.png"> 13 24 25 + <style> 14 26 15 27 16 28 ··· 215 227 216 228 217 229 230 + <meta property="og:type" content="website"> 231 + <meta property="og:url" content="https://at-me.fly.dev/"> 232 + <meta property="og:title" content="@me - explore your atproto identity"> 233 + <meta property="og:description" content="visualize your decentralized identity and see what apps have stored data in your Personal Data Server"> 234 + <meta property="og:image" content="https://at-me.fly.dev/static/og-image.png"> 218 235 236 + <!-- Twitter --> 237 + <meta property="twitter:card" content="summary_large_image"> 238 + <meta property="twitter:url" content="https://at-me.fly.dev/"> 239 + <meta property="twitter:title" content="@me - explore your atproto identity"> 240 + <meta property="twitter:description" content="visualize your decentralized identity and see what apps have stored data in your Personal Data Server"> 241 + <meta property="twitter:image" content="https://at-me.fly.dev/static/og-image.png"> 219 242 243 + <style> 220 244 221 245 222 246 ··· 851 875 852 876 853 877 878 + .onboarding-progress span.done {{ 879 + background: var(--text-light); 880 + }} 854 881 882 + .stats-box {{ 883 + display: flex; 884 + gap: 1.5rem; 885 + margin: 1.5rem 0; 886 + padding: 1rem; 887 + background: var(--bg); 888 + border-radius: 4px; 889 + border: 1px solid var(--border); 890 + }} 855 891 892 + .stat {{ 893 + flex: 1; 894 + text-align: center; 895 + }} 856 896 897 + .stat-value {{ 898 + font-size: 1.8rem; 899 + font-weight: 600; 900 + color: var(--text); 901 + margin-bottom: 0.25rem; 902 + }} 857 903 904 + .stat-label {{ 905 + font-size: 0.65rem; 906 + color: var(--text-light); 907 + text-transform: uppercase; 908 + letter-spacing: 0.05em; 909 + }} 858 910 911 + .ownership-box {{ 912 + margin: 1rem 0; 913 + padding: 1rem; 914 + background: var(--bg); 915 + border-radius: 4px; 916 + border: 1px solid var(--border); 917 + }} 859 918 919 + .ownership-box.yours {{ 920 + background: rgba(76, 175, 80, 0.05); 921 + border-color: rgba(76, 175, 80, 0.3); 922 + }} 860 923 924 + @media (prefers-color-scheme: dark) {{ 925 + .ownership-box.yours {{ 926 + background: rgba(76, 175, 80, 0.08); 927 + border-color: rgba(76, 175, 80, 0.4); 928 + }} 929 + }} 861 930 931 + .ownership-header {{ 932 + font-size: 0.7rem; 933 + font-weight: 600; 934 + color: var(--text); 935 + margin-bottom: 0.5rem; 936 + text-transform: uppercase; 937 + letter-spacing: 0.05em; 938 + }} 862 939 940 + .ownership-text {{ 941 + font-size: 0.7rem; 942 + color: var(--text-lighter); 943 + line-height: 1.5; 944 + }} 863 945 864 - 865 - 866 - 867 - 868 - 869 - 870 - 871 - 872 - 873 - 874 - 875 - 876 - 877 - 878 - .onboarding-progress span.done {{ 879 - background: var(--text-light); 946 + .ownership-text strong {{ 947 + color: var(--text); 880 948 }} 881 949 </style> 882 950 </head> ··· 886 954 887 955 <div class="overlay" id="overlay"></div> 888 956 <div class="info-modal" id="infoModal"> 889 - <h2>@me - your at protocol identity</h2> 890 - <p>in decentralized social networks, you own your identity and your data lives in your personal data server (pds).</p> 891 - <p>third-party applications create records in your repository using different lexicons (data schemas). for example, bluesky creates posts, white wind stores blog entries, tangled.org hosts code repositories, and frontpage aggregates links - all in the same place.</p> 892 - <p>this visualization shows your identity at the center, surrounded by the third-party apps that have created data for you. click an app to see what types of records it stores, then click a record type to see the actual data.</p> 957 + <h2>@me - your repository</h2> 958 + <p>on traditional social platforms, your content is locked in. want to switch? you start from zero. you build their network, they control the distribution.</p> 959 + <p>on atproto, you own everything. your data lives in your <a href="https://atproto.com/guides/overview" target="_blank" rel="noopener noreferrer" style="color: var(--text); text-decoration: underline;">Personal Data Server (PDS)</a>. apps like bluesky, whitewind, and frontpage just write to YOUR space. switch apps anytime, take it all with you.</p> 960 + <p>click your @ in the center to see what you've built. click any app to see what it's stored in your repository.</p> 893 961 <button id="closeInfo">got it</button> 894 962 <button id="restartTour" onclick="window.restartOnboarding()" style="margin-left: 0.5rem; background: var(--surface-hover);">restart tour</button> 895 963 </div>
+66 -31
static/app.js
··· 93 93 // User may not have an avatar set 94 94 }); 95 95 96 - // Add identity click handler to show PDS info 96 + // Store collections and apps for later use 97 + let allCollections = []; 98 + let apps = {}; 99 + 100 + // Get all collections from PDS 101 + return fetch(`${pds}/xrpc/com.atproto.repo.describeRepo?repo=${did}`); 102 + }) 103 + .then(r => r.json()) 104 + .then(repo => { 105 + const collections = repo.collections || []; 106 + allCollections = collections; 107 + 108 + // Group by app namespace (first two parts of lexicon) 109 + apps = {}; 110 + collections.forEach(collection => { 111 + const parts = collection.split('.'); 112 + if (parts.length >= 2) { 113 + const namespace = `${parts[0]}.${parts[1]}`; 114 + if (!apps[namespace]) apps[namespace] = []; 115 + apps[namespace].push(collection); 116 + } 117 + }); 118 + 119 + // Add identity click handler now that we have the data 120 + const pdsHost = globalPds.replace('https://', '').replace('http://', ''); 97 121 document.querySelector('.identity').addEventListener('click', () => { 98 122 const detail = document.getElementById('detail'); 99 - const pdsHost = pds.replace('https://', '').replace('http://', ''); 123 + const appCount = Object.keys(apps).length; 124 + 100 125 detail.innerHTML = ` 101 126 <button class="detail-close" id="detailClose">×</button> 102 - <h3>your identity</h3> 103 - <div class="subtitle">decentralized identifier & storage</div> 104 - <div class="tree-item"> 105 - <div class="tree-item-header"> 106 - <span style="color: var(--text-light);">did</span> 107 - <span style="font-size: 0.6rem; color: var(--text);">${did}</span> 127 + <h3>your repository</h3> 128 + <div class="subtitle">what you've built</div> 129 + 130 + <div class="stats-box"> 131 + <div class="stat"> 132 + <div class="stat-value">${allCollections.length}</div> 133 + <div class="stat-label">record types</div> 108 134 </div> 109 - </div> 110 - <div class="tree-item"> 111 - <div class="tree-item-header"> 112 - <span style="color: var(--text-light);">handle</span> 113 - <span style="font-size: 0.6rem; color: var(--text);">@${handle}</span> 135 + <div class="stat"> 136 + <div class="stat-value">${appCount}</div> 137 + <div class="stat-label">apps</div> 114 138 </div> 115 139 </div> 116 - <div class="tree-item"> 117 - <div class="tree-item-header"> 118 - <span style="color: var(--text-light);">personal data server</span> 119 - <span style="font-size: 0.6rem; color: var(--text);">${pds}</span> 120 - </div> 140 + 141 + <div class="ownership-box"> 142 + <div class="ownership-header">on traditional platforms</div> 143 + <div class="ownership-text">your content is locked in. switching platforms means starting over. you build their network, they own the distribution.</div> 121 144 </div> 122 - <div style="margin-top: 1rem; padding: 0.6rem; background: var(--bg); border-radius: 4px; font-size: 0.65rem; line-height: 1.5; color: var(--text-lighter);"> 123 - your data lives at <strong style="color: var(--text);">${pdsHost}</strong>. apps like bluesky write to and read from this server. you control @<strong style="color: var(--text);">${handle}</strong> and can move it to a different server anytime. 145 + 146 + <div class="ownership-box yours"> 147 + <div class="ownership-header">on atproto</div> 148 + <div class="ownership-text">your content, your server. apps just read and write to <strong>${pdsHost}</strong>. switch apps anytime, take your data anywhere.</div> 124 149 </div> 150 + 151 + <div style="margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--border);"> 152 + <div style="font-size: 0.65rem; color: var(--text-light); margin-bottom: 0.5rem;">technical details</div> 153 + <div class="tree-item"> 154 + <div class="tree-item-header"> 155 + <span style="color: var(--text-light);">did</span> 156 + <span style="font-size: 0.55rem; color: var(--text);">${did}</span> 157 + </div> 158 + </div> 159 + <div class="tree-item"> 160 + <div class="tree-item-header"> 161 + <span style="color: var(--text-light);">handle</span> 162 + <span style="font-size: 0.6rem; color: var(--text);">@${globalHandle}</span> 163 + </div> 164 + </div> 165 + </div> 125 166 `; 126 167 detail.classList.add('visible'); 127 168 ··· 129 170 130 171 131 172 173 + }); 174 + }); 132 175 133 - 134 - 135 - 136 - 137 - 138 - .then(r => r.json()) 139 - .then(repo => { 140 - const collections = repo.collections || []; 141 - 142 - // Group by app namespace (first two parts of lexicon) 143 - const apps = {}; 176 + const field = document.getElementById('field'); 177 + field.innerHTML = ''; 178 + field.classList.remove('loading');
+3 -3
static/onboarding.js
··· 5 5 { 6 6 target: '.identity', 7 7 title: 'this is you', 8 - description: 'your global identity and handle. your data is hosted at your personal data server (pds).', 8 + description: 'your global identity and handle. your data is hosted at your <a href="https://atproto.com/guides/overview" target="_blank" rel="noopener noreferrer" style="color: inherit; text-decoration: underline;">Personal Data Server (PDS)</a>.', 9 9 position: 'bottom' 10 10 }, 11 11 { 12 12 target: '.canvas', 13 13 title: 'third-party applications', 14 - description: 'these apps use your global identity to write public records to your pds. they can also read records you\'ve created.', 14 + description: 'these apps use your global identity to write public records to your PDS. they can also read records you\'ve created.', 15 15 position: 'center' 16 16 }, 17 17 { 18 18 target: '.app-view', 19 19 title: 'explore your records', 20 - description: 'click any app to see what records it has written to your pds.', 20 + description: 'click any app to see what records it has written to your PDS.', 21 21 position: 'bottom' 22 22 } 23 23 ];

History

1 round 0 comments
sign up or login to add to the discussion
zzstoatzz.io submitted #0
4 commits
expand
feat: add ownership visualization and silo comparison
fix: scope issue with apps variable and soften messaging
feat: capitalize PDS and add link to official docs
feat: link PDS in first onboarding step to official docs
expand 0 comments
pull request successfully merged