tangled
alpha
login
or
join now
djara.dev
/
watproto
2
fork
atom
Testing implementation for private data in ATProto with ATPKeyserver and ATCute tools
2
fork
atom
overview
issues
pulls
pipelines
ui to see feeds from different users
Juan D. Jara
5 months ago
5ed56872
fb890688
+50
-19
4 changed files
expand all
collapse all
unified
split
packages
client
app
components
PostFeed.tsx
lib
post.server.ts
routes
_index.tsx
user.$handle.tsx
+5
packages/client/app/components/PostFeed.tsx
reviewed
···
9
9
export default function PostFeed({ feed }: { feed: FeedItem[] }) {
10
10
return (
11
11
<ul className="divide-accent-content">
12
12
+
{feed.length === 0 ? (
13
13
+
<li className="p-4">
14
14
+
<p className="text-center">No posts here</p>
15
15
+
</li>
16
16
+
) : null}
12
17
{feed.map((post) => (
13
18
<li
14
19
key={post.uri}
+15
-2
packages/client/app/lib/post.server.ts
reviewed
···
3
3
parse,
4
4
parseCanonicalResourceUri,
5
5
type Did,
6
6
+
type Handle,
6
7
type ResourceUri
7
8
} from '@atcute/lexicons'
8
9
import { createKeyClient, getServiceAgent, getSessionAgent } from './xrpcClient'
···
129
130
visibility: (string & {}) | 'followers' | 'mentioned' | 'public'
130
131
}
131
132
132
132
-
export async function getFeed(request: Request) {
133
133
+
export async function getFeed(request: Request, handle?: Handle) {
133
134
const serviceDid =
134
135
`did:web:${encodeURIComponent(new URL(env.API_URL).host)}` as const
135
136
const session = await getOAuthSession(request)
136
137
const serverClient = await getServiceAgent(session, serviceDid)
137
138
const keyClient = createKeyClient(session)
139
139
+
let did = session.did as Did
140
140
+
if (handle) {
141
141
+
const foundDid = await handleToDid(handle)
142
142
+
if (foundDid) {
143
143
+
did = foundDid
144
144
+
}
145
145
+
}
138
146
139
147
const { feed } = await ok(
140
148
serverClient.get('app.wafrn.content.getFeed', {
141
141
-
params: { did: session.did }
149
149
+
params: { did }
142
150
})
143
151
)
144
152
···
192
200
const didDoc = await idResolver.did.resolveAtprotoData(did)
193
201
return didDoc.handle
194
202
}
203
203
+
204
204
+
async function handleToDid(handle: Handle) {
205
205
+
const did = await idResolver.handle.resolve(handle)
206
206
+
return did as Did | undefined
207
207
+
}
+10
-17
packages/client/app/routes/_index.tsx
reviewed
···
1
1
import { useRootData } from '@www/lib/useRootData'
2
2
import { Link } from 'react-router'
3
3
-
import type { Route } from './+types/_index'
4
4
-
import { getFeed } from '@www/lib/post.server'
5
5
-
import { useLoaderData } from 'react-router'
6
6
-
import PostFeed from '@www/components/PostFeed'
7
3
8
4
export function meta() {
9
5
return [
10
6
{ title: 'New React Router App' },
11
7
{ name: 'description', content: 'Welcome to React Router!' }
12
8
]
13
13
-
}
14
14
-
15
15
-
export async function loader({ request }: Route.LoaderArgs) {
16
16
-
try {
17
17
-
const feed = await getFeed(request)
18
18
-
return { feed }
19
19
-
} catch (err) {
20
20
-
console.error(err)
21
21
-
return { feed: [] }
22
22
-
}
23
9
}
24
10
25
11
export default function Home() {
26
12
const { user } = useRootData()
27
27
-
const { feed } = useLoaderData<typeof loader>()
28
28
-
console.log('client feed: ', feed)
29
13
30
14
return (
31
15
<div className="p-4 max-w-3xl mx-auto">
···
40
24
</Link>
41
25
)}
42
26
</p>
43
43
-
<PostFeed feed={feed} />
27
27
+
<p>
28
28
+
<Link className="btn btn-link" to="/user/blt.pds.djara.dev">
29
29
+
See posts from @blt.pds.djara.dev
30
30
+
</Link>
31
31
+
</p>
32
32
+
<p>
33
33
+
<Link className="btn btn-link" to="/user/user2.pds.djara.dev">
34
34
+
See posts from @user2.pds.djara.dev
35
35
+
</Link>
36
36
+
</p>
44
37
</div>
45
38
)
46
39
}
+20
packages/client/app/routes/user.$handle.tsx
reviewed
···
1
1
+
import type { Route } from './+types/user.$handle'
2
2
+
import { getFeed } from '@www/lib/post.server'
3
3
+
import type { Handle } from '@atcute/lexicons'
4
4
+
import { useLoaderData } from 'react-router'
5
5
+
import PostFeed from '@www/components/PostFeed'
6
6
+
7
7
+
export async function loader({ request, params }: Route.LoaderArgs) {
8
8
+
const feed = await getFeed(request, params.handle as Handle)
9
9
+
return { feed }
10
10
+
}
11
11
+
12
12
+
export default function UserPage() {
13
13
+
const { feed } = useLoaderData<typeof loader>()
14
14
+
15
15
+
return (
16
16
+
<div>
17
17
+
<PostFeed feed={feed} />
18
18
+
</div>
19
19
+
)
20
20
+
}