From ab0c093a90bc46cb75dcb2035a29c8fb8e70038b Mon Sep 17 00:00:00 2001 From: zzstoatzz Date: Thu, 9 Oct 2025 02:06:21 -0500 Subject: [PATCH] feat: add ownership visualization and silo comparison - show stats (record types, apps) when clicking identity - contrast walled gardens vs atproto ownership - update info modal to emphasize ownership - add visual styling for ownership boxes --- src/templates.rs | 76 +++++++++++++++++++++++++++++++++++++++++++++--- static/app.js | 60 ++++++++++++++++++++++++++------------ 2 files changed, 114 insertions(+), 22 deletions(-) diff --git a/src/templates.rs b/src/templates.rs index 4522e91..496cbb1 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -878,6 +878,74 @@ pub fn app_page(did: &str) -> String { .onboarding-progress span.done {{ background: var(--text-light); }} + + .stats-box {{ + display: flex; + gap: 1.5rem; + margin: 1.5rem 0; + padding: 1rem; + background: var(--bg); + border-radius: 4px; + border: 1px solid var(--border); + }} + + .stat {{ + flex: 1; + text-align: center; + }} + + .stat-value {{ + font-size: 1.8rem; + font-weight: 600; + color: var(--text); + margin-bottom: 0.25rem; + }} + + .stat-label {{ + font-size: 0.65rem; + color: var(--text-light); + text-transform: uppercase; + letter-spacing: 0.05em; + }} + + .ownership-box {{ + margin: 1rem 0; + padding: 1rem; + background: var(--bg); + border-radius: 4px; + border: 1px solid var(--border); + }} + + .ownership-box.yours {{ + background: rgba(76, 175, 80, 0.05); + border-color: rgba(76, 175, 80, 0.3); + }} + + @media (prefers-color-scheme: dark) {{ + .ownership-box.yours {{ + background: rgba(76, 175, 80, 0.08); + border-color: rgba(76, 175, 80, 0.4); + }} + }} + + .ownership-header {{ + font-size: 0.7rem; + font-weight: 600; + color: var(--text); + margin-bottom: 0.5rem; + text-transform: uppercase; + letter-spacing: 0.05em; + }} + + .ownership-text {{ + font-size: 0.7rem; + color: var(--text-lighter); + line-height: 1.5; + }} + + .ownership-text strong {{ + color: var(--text); + }} @@ -886,10 +954,10 @@ pub fn app_page(did: &str) -> String {
-

@me - your at protocol identity

-

in decentralized social networks, you own your identity and your data lives in your personal data server (pds).

-

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.

-

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.

+

@me - your repository

+

on instagram, facebook, or twitter: the platform owns your content. if they ban you, it's all gone. you can't move it, export it, or control who accesses it.

+

on atproto: you own everything. your data lives in your personal server. apps like bluesky, whitewind, and frontpage just write to YOUR repository. you can switch apps, move servers, or revoke access anytime.

+

click your @ in the center to see what you've built. click any app to see what it's stored in your space.

diff --git a/static/app.js b/static/app.js index 68745cf..f505a89 100644 --- a/static/app.js +++ b/static/app.js @@ -93,34 +93,57 @@ fetch('https://plc.directory/' + did) // User may not have an avatar set }); + // Store collections for later use + let allCollections = []; + // Add identity click handler to show PDS info document.querySelector('.identity').addEventListener('click', () => { const detail = document.getElementById('detail'); const pdsHost = pds.replace('https://', '').replace('http://', ''); + + // Count total apps + const appCount = Object.keys(apps).length; + detail.innerHTML = ` -

your identity

-
decentralized identifier & storage
-
-
- did - ${did} +

your repository

+
what you've built
+ +
+
+
${allCollections.length}
+
record types
-
-
-
- handle - @${handle} +
+
${appCount}
+
apps
-
-
- personal data server - ${pds} -
+ +
+
on walled gardens
+
platform owns your content. account ban = everything gone. no export, no control.
+
+ +
+
on atproto
+
you own it. lives at ${pdsHost}. move servers, switch apps, export anytime. can't be taken away.
-
- your data lives at ${pdsHost}. apps like bluesky write to and read from this server. you control @${handle} and can move it to a different server anytime. + +
+
technical details
+
+
+ did + ${did} +
+
+
+
+ handle + @${handle} +
+
`; detail.classList.add('visible'); @@ -138,6 +161,7 @@ fetch('https://plc.directory/' + did) .then(r => r.json()) .then(repo => { const collections = repo.collections || []; + allCollections = collections; // Group by app namespace (first two parts of lexicon) const apps = {}; -- 2.43.0 From 91da2cf479bc54e971aa9dab5091dec656e83846 Mon Sep 17 00:00:00 2001 From: zzstoatzz Date: Thu, 9 Oct 2025 09:08:41 -0500 Subject: [PATCH] fix: scope issue with apps variable and soften messaging - move identity click handler after apps is populated - change messaging from ban-focused to lock-in/distribution focused - emphasize 'you build their network, they own distribution' - softer language: locked in vs can't export, starting over vs gone --- src/templates.rs | 6 +++--- static/app.js | 55 ++++++++++++++++++++++++------------------------ 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/templates.rs b/src/templates.rs index 496cbb1..4ae5fc4 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -955,9 +955,9 @@ pub fn app_page(did: &str) -> String {

@me - your repository

-

on instagram, facebook, or twitter: the platform owns your content. if they ban you, it's all gone. you can't move it, export it, or control who accesses it.

-

on atproto: you own everything. your data lives in your personal server. apps like bluesky, whitewind, and frontpage just write to YOUR repository. you can switch apps, move servers, or revoke access anytime.

-

click your @ in the center to see what you've built. click any app to see what it's stored in your space.

+

on traditional social platforms, your content is locked in. want to switch? you start from zero. you build their network, they control the distribution.

+

on atproto, you own everything. your data lives in your personal server. apps like bluesky, whitewind, and frontpage just write to YOUR space. switch apps anytime, take it all with you.

+

click your @ in the center to see what you've built. click any app to see what it's stored in your repository.

diff --git a/static/app.js b/static/app.js index f505a89..de63b54 100644 --- a/static/app.js +++ b/static/app.js @@ -93,15 +93,33 @@ fetch('https://plc.directory/' + did) // User may not have an avatar set }); - // Store collections for later use + // Store collections and apps for later use let allCollections = []; + let apps = {}; - // Add identity click handler to show PDS info + // Get all collections from PDS + return fetch(`${pds}/xrpc/com.atproto.repo.describeRepo?repo=${did}`); + }) + .then(r => r.json()) + .then(repo => { + const collections = repo.collections || []; + allCollections = collections; + + // Group by app namespace (first two parts of lexicon) + apps = {}; + collections.forEach(collection => { + const parts = collection.split('.'); + if (parts.length >= 2) { + const namespace = `${parts[0]}.${parts[1]}`; + if (!apps[namespace]) apps[namespace] = []; + apps[namespace].push(collection); + } + }); + + // Add identity click handler now that we have the data + const pdsHost = globalPds.replace('https://', '').replace('http://', ''); document.querySelector('.identity').addEventListener('click', () => { const detail = document.getElementById('detail'); - const pdsHost = pds.replace('https://', '').replace('http://', ''); - - // Count total apps const appCount = Object.keys(apps).length; detail.innerHTML = ` @@ -121,13 +139,13 @@ fetch('https://plc.directory/' + did)
-
on walled gardens
-
platform owns your content. account ban = everything gone. no export, no control.
+
on traditional platforms
+
your content is locked in. switching platforms means starting over. you build their network, they own the distribution.
on atproto
-
you own it. lives at ${pdsHost}. move servers, switch apps, export anytime. can't be taken away.
+
your content, your server. apps just read and write to ${pdsHost}. switch apps anytime, take your data anywhere.
@@ -141,7 +159,7 @@ fetch('https://plc.directory/' + did)
handle - @${handle} + @${globalHandle}
@@ -155,25 +173,6 @@ fetch('https://plc.directory/' + did) }); }); - // Get all collections from PDS - return fetch(`${pds}/xrpc/com.atproto.repo.describeRepo?repo=${did}`); - }) - .then(r => r.json()) - .then(repo => { - const collections = repo.collections || []; - allCollections = collections; - - // Group by app namespace (first two parts of lexicon) - const apps = {}; - collections.forEach(collection => { - const parts = collection.split('.'); - if (parts.length >= 2) { - const namespace = `${parts[0]}.${parts[1]}`; - if (!apps[namespace]) apps[namespace] = []; - apps[namespace].push(collection); - } - }); - const field = document.getElementById('field'); field.innerHTML = ''; field.classList.remove('loading'); -- 2.43.0 From f44899d6c406a7b62244e4c92f45f0fe275faa10 Mon Sep 17 00:00:00 2001 From: zzstoatzz Date: Thu, 9 Oct 2025 09:21:37 -0500 Subject: [PATCH] feat: capitalize PDS and add link to official docs - capitalize Personal Data Server (PDS) throughout - link first mention in info modal to atproto.com/guides/overview - update meta descriptions and onboarding text --- src/templates.rs | 10 +++++----- static/onboarding.js | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/templates.rs b/src/templates.rs index 4ae5fc4..5331df6 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -12,14 +12,14 @@ pub fn login_page() -> &'static str { - + - +