+13
README.md
+13
README.md
···
1
+
# katproto index
2
+
3
+
these are the files that make up the [katproto](https://katproto.girlonthemoon.xyz/) PDS index page.
4
+
5
+
the dynamic user list is modified (honestly, mostly copy pasted) from a script by [@vielle.dev](https://tangled.org/@vielle.dev/server-config/blob/master/landing/landing.ts). to make it work client-side, run the below commands:
6
+
7
+
```bash
8
+
# git clone & cd to the repo folder
9
+
10
+
npm install
11
+
12
+
npx tsc --p tsconfig.json
13
+
```
+170
index.html
+170
index.html
···
1
+
<!DOCTYPE html>
2
+
<html lang="en">
3
+
<head>
4
+
<meta charset="UTF-8" />
5
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+
7
+
<meta name="title" content="girl on the moon :: atproto" />
8
+
<meta name="description" content="girl on the moon PDS" />
9
+
<meta name="author" content="girlonthemoon.xyz" />
10
+
<meta property="og:title" content="girl on the moon :: atproto" />
11
+
<meta property="og:description" content="girl on the moon PDS" />
12
+
<meta property="og:type" content="website" />
13
+
<meta property="og:url" content="https://katproto.girlonthemoon.xyz" />
14
+
<meta property="og:image" content="https://stash.4-walls.net/pics/pochacco.jpg" />
15
+
16
+
<link rel="canonical" href="https://katproto.girlonthemoon.xyz" />
17
+
<link rel="icon" type="image/png" sizes="64x64" href="https://stash.4-walls.net/pics/pochacco_favicon.png" />
18
+
19
+
<script src="https://stash.4-walls.net/katproto_demo/katproto_users.js"></script>
20
+
21
+
<title>katproto</title>
22
+
23
+
<style>
24
+
@import url(https://fonts.bunny.net/css?family=victor-mono:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i);
25
+
26
+
:root {
27
+
--font: "Victor Mono", monospace;
28
+
--main-color: #ff69b4;
29
+
}
30
+
31
+
body {
32
+
font-family: var(--font) !important;
33
+
counter-reset: Span-count;
34
+
font-size: .9rem;
35
+
}
36
+
37
+
pre {
38
+
font-family: var(--font) !important;
39
+
margin: 0 !important;
40
+
padding: 0 !important;
41
+
}
42
+
43
+
.nosc {
44
+
font-family: var(--font) !important;
45
+
font-size: .9rem;
46
+
}
47
+
48
+
div[aria-label] {
49
+
margin: 0 !important;
50
+
padding: 0 !important;
51
+
}
52
+
53
+
pre h1 {
54
+
color: var(--main-color);
55
+
margin: 0 0 0 1rem;
56
+
padding: 0 !important;
57
+
font-style: italic;
58
+
}
59
+
60
+
h2 {
61
+
color: var(--main-color);
62
+
padding: 0 !important;
63
+
font-style: italic;
64
+
}
65
+
66
+
a {
67
+
text-underline-offset: 4px;
68
+
color: var(--main-color);
69
+
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
70
+
}
71
+
72
+
dfn, i {
73
+
color: var(--main-color);
74
+
}
75
+
76
+
a:hover {
77
+
text-decoration: none;
78
+
text-shadow: none;
79
+
}
80
+
81
+
hr {
82
+
border: 1px dashed var(--main-color);
83
+
width: 40%;
84
+
margin: 1rem 1rem 1rem 0;
85
+
padding: 0;
86
+
}
87
+
88
+
#not-pre {
89
+
margin: 0 0 0 1rem;
90
+
}
91
+
92
+
#list-users {
93
+
font-family: var(--font);
94
+
font-size: .9rem;
95
+
margin: 0 !important;
96
+
padding: 0 !important;
97
+
}
98
+
99
+
.user-count {
100
+
counter-increment: Span-count;
101
+
display: inline-block;
102
+
margin-bottom: .5rem;
103
+
}
104
+
105
+
.user-count:before {
106
+
content: counter(Span-count) ". ";
107
+
}
108
+
</style>
109
+
</head>
110
+
111
+
<body>
112
+
113
+
<pre>
114
+
<div aria-label="ASCII text art of pochacco" role="img">
115
+
,8,
116
+
d8b
117
+
888
118
+
__ , 888
119
+
d88888b. -.\,- 888
120
+
`Y8888b."```"-888
121
+
/`" `8\
122
+
| |
123
+
| |
124
+
| |
125
+
__ / O _ O \
126
+
/` '.\ '-' /
127
+
\ .'. .;
128
+
'. .' `"""""""` \
129
+
`\ /.-.|
130
+
`| |` |
131
+
| \___/
132
+
;-.._______..-;
133
+
jgs / | \
134
+
\___,---'---,___/
135
+
</div>
136
+
<h1 id="katproto">katproto</h1>
137
+
this is an at protocol <dfn>personal data server</dfn> (aka, an atproto PDS); more specifically, it's <a href="https://girlonthemoon.xyz/">kat</a>'s PDS!
138
+
</pre>
139
+
140
+
<div id="not-pre">
141
+
<hr>
142
+
143
+
<h2 id="users">users</h2>
144
+
145
+
<div id="list-users">
146
+
</div>
147
+
148
+
<hr>
149
+
150
+
<noscript>
151
+
<span class="nosc">sorry, to see the dynamic list of users, you must have javascript enabled!</span>
152
+
<hr>
153
+
</noscript>
154
+
155
+
<script>
156
+
async function printUsers() {
157
+
document.getElementById("list-users").innerHTML = await getKatprotoUsers();
158
+
}
159
+
printUsers();
160
+
</script>
161
+
162
+
<h2 id="credits">credits</h2>
163
+
164
+
<p>
165
+
PDS: <a href="https://github.com/bluesky-social/pds">github.com/bluesky-social/pds</a><br>
166
+
dynamic user list: <a href="https://tangled.org/@vielle.dev/server-config/blob/master/landing/landing.ts">most of the code here</a><br>
167
+
</p>
168
+
</div>
169
+
170
+
</html>
+39
katproto_users.ts
+39
katproto_users.ts
···
1
+
async function getKatprotoUsers() {
2
+
const users = fetch("https://katproto.girlonthemoon.xyz/xrpc/com.atproto.sync.listRepos")
3
+
// type cast because no point validating for smthn like this
4
+
// real type has more info; not needed here
5
+
.then((res) => res.json() as Promise<{ repos: { did: string }[] }>)
6
+
.then((res) =>
7
+
// get display name, handle, and did for each user
8
+
res.repos.map((repo) => ({
9
+
display: fetch(
10
+
`https://katproto.girlonthemoon.xyz/xrpc/com.atproto.repo.getRecord?repo=${repo.did}&collection=app.bsky.actor.profile&rkey=self`
11
+
)
12
+
.then((res) => res.json())
13
+
.then((profile) => profile.value.displayName),
14
+
// dont validate handles because I'm Lazy + trust myself
15
+
handle: fetch(
16
+
repo.did.startsWith("did:plc")
17
+
? "https://plc.directory/" + repo.did
18
+
: `https://${repo.did.replace("did:web:", "")}/.well-known/did.json`
19
+
)
20
+
.then((res) => res.json())
21
+
.then((doc) => doc.alsoKnownAs[0].replace("at://", "")),
22
+
did: repo.did
23
+
}))
24
+
)
25
+
.then(async (users) =>
26
+
(
27
+
await Promise.all(
28
+
users.map(
29
+
async (x) =>
30
+
`<span class="user-count"><a href="https://bsky.app/profile/${x.did}">${await x.display}</a></span>`
31
+
)
32
+
)
33
+
)
34
+
)
35
+
const fin = Array.from(await users).join("<br>");
36
+
return (await fin);
37
+
};
38
+
39
+
getKatprotoUsers();
+25
package-lock.json
+25
package-lock.json
···
1
+
{
2
+
"name": "bsky",
3
+
"lockfileVersion": 3,
4
+
"requires": true,
5
+
"packages": {
6
+
"": {
7
+
"dependencies": {
8
+
"typescript": "^5.9.2"
9
+
}
10
+
},
11
+
"node_modules/typescript": {
12
+
"version": "5.9.2",
13
+
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
14
+
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
15
+
"license": "Apache-2.0",
16
+
"bin": {
17
+
"tsc": "bin/tsc",
18
+
"tsserver": "bin/tsserver"
19
+
},
20
+
"engines": {
21
+
"node": ">=14.17"
22
+
}
23
+
}
24
+
}
25
+
}
+6
package.json
+6
package.json
pic.png
pic.png
This is a binary file and will not be displayed.
pochacco.jpg
pochacco.jpg
This is a binary file and will not be displayed.
+12
tsconfig.json
+12
tsconfig.json