+2
-23
src/state/queries/deer-verification.ts
+2
-23
src/state/queries/deer-verification.ts
···
23
23
constellationLinks,
24
24
} from './constellation'
25
25
import {LRU} from './direct-fetch-record'
26
+
import {resolvePdsServiceUrl} from './resolve-identity'
26
27
import {useCurrentAccountProfile} from './useCurrentAccountProfile'
27
28
28
29
const RQKEY_ROOT = 'deer-verification'
···
36
37
link: ConstellationLink
37
38
record: AppBskyGraphVerification.Record
38
39
}
39
-
40
-
// TODO: lift this into direct fetch to share cache
41
-
const serviceCache = new LRU<`did:${string}`, string>()
42
40
43
41
const verificationCache = new LRU<string, any>()
44
42
···
82
80
async link => {
83
81
const {did, rkey} = link
84
82
85
-
let service = await serviceCache.getOrTryInsertWith(did, async () => {
86
-
const docUrl = did.startsWith('did:plc:')
87
-
? `https://plc.directory/${did}`
88
-
: `https://${did.substring(8)}/.well-known/did.json`
89
-
90
-
// TODO: validate!
91
-
const doc: {
92
-
service: {
93
-
serviceEndpoint: string
94
-
type: string
95
-
}[]
96
-
} = await (await fetch(docUrl)).json()
97
-
const service = doc.service.find(
98
-
s => s.type === 'AtprotoPersonalDataServer',
99
-
)?.serviceEndpoint
100
-
101
-
if (service === undefined)
102
-
throw new Error(`could not find a service for ${did}`)
103
-
return service
104
-
})
83
+
let service = await resolvePdsServiceUrl(did)
105
84
106
85
const request = `${service}/xrpc/com.atproto.repo.getRecord?repo=${did}&collection=app.bsky.graph.verification&rkey=${rkey}`
107
86
const record = await verificationCache.getOrTryInsertWith(
+26
src/state/queries/resolve-identity.ts
+26
src/state/queries/resolve-identity.ts
···
1
+
import {LRU} from './direct-fetch-record'
2
+
3
+
const serviceCache = new LRU<`did:${string}`, string>()
4
+
5
+
export async function resolvePdsServiceUrl(did: `did:${string}`) {
6
+
return await serviceCache.getOrTryInsertWith(did, async () => {
7
+
const docUrl = did.startsWith('did:plc:')
8
+
? `https://plc.directory/${did}`
9
+
: `https://${did.substring(8)}/.well-known/did.json`
10
+
11
+
// TODO: validate!
12
+
const doc: {
13
+
service: {
14
+
serviceEndpoint: string
15
+
type: string
16
+
}[]
17
+
} = await (await fetch(docUrl)).json()
18
+
const service = doc.service.find(
19
+
s => s.type === 'AtprotoPersonalDataServer',
20
+
)?.serviceEndpoint
21
+
22
+
if (service === undefined)
23
+
throw new Error(`could not find a service for ${did}`)
24
+
return service
25
+
})
26
+
}
+5
-2
src/view/com/util/forms/PostDropdownBtnMenuItems.tsx
+5
-2
src/view/com/util/forms/PostDropdownBtnMenuItems.tsx
···
52
52
useProfileBlockMutationQueue,
53
53
useProfileMuteMutationQueue,
54
54
} from '#/state/queries/profile'
55
+
import {resolvePdsServiceUrl} from '#/state/queries/resolve-identity'
55
56
import {useToggleReplyVisibilityMutation} from '#/state/queries/threadgate'
56
57
import {useSession} from '#/state/session'
57
58
import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies'
···
396
397
const video = post.embed as AppBskyEmbedVideo.View
397
398
const did = post.author.did
398
399
const cid = video.cid
399
-
const uri = `https://bsky.social/xrpc/com.atproto.sync.getBlob?did=${did}&cid=${cid}`
400
+
if (!did.startsWith('did:')) return
401
+
const pdsUrl = await resolvePdsServiceUrl(did as `did:${string}`)
402
+
const uri = `${pdsUrl}/xrpc/com.atproto.sync.getBlob?did=${did}&cid=${cid}`
400
403
401
404
Toast.show('Downloading video...', 'download')
402
405
···
427
430
const embed = post.embed as AppBskyEmbedExternal.View
428
431
// Janky workaround by checking if the domain is tenor.com
429
432
const url = new URL(embed.external.uri)
430
-
return url.host == 'media.tenor.com'
433
+
return url.host === 'media.tenor.com'
431
434
}, [post])
432
435
433
436
const onBlockAuthor = useCallback(async () => {