ai/at
1
0

fix social-app service link pds

This commit is contained in:
2026-02-16 13:07:09 +09:00
parent c09738f342
commit 8db064d8c0
5 changed files with 112 additions and 7 deletions

Binary file not shown.

View File

@@ -7,20 +7,19 @@
import { import {
type AppBskyActorDefs, type AppBskyActorDefs,
moderateProfile, moderateProfile,
@@ -9,9 +9,12 @@ @@ -9,9 +9,11 @@
} from '@atproto/api' } from '@atproto/api'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
+import {useQuery} from '@tanstack/react-query' +import {useQuery} from '@tanstack/react-query'
import {useActorStatus} from '#/lib/actor-status' import {useActorStatus} from '#/lib/actor-status'
+import {BSKY_SERVICE} from '#/lib/constants'
import {useHaptics} from '#/lib/haptics' import {useHaptics} from '#/lib/haptics'
+import {useOpenLink} from '#/lib/hooks/useOpenLink' +import {useOpenLink} from '#/lib/hooks/useOpenLink'
import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles' import {sanitizeHandle} from '#/lib/strings/handles'
import {logger} from '#/logger' import {logger} from '#/logger'
@@ -45,6 +48,84 @@ @@ -45,6 +47,103 @@
import {ProfileHeaderMetrics} from './Metrics' import {ProfileHeaderMetrics} from './Metrics'
import {ProfileHeaderShell} from './Shell' import {ProfileHeaderShell} from './Shell'
import {ProfileHeaderSuggestedFollows} from './SuggestedFollows' import {ProfileHeaderSuggestedFollows} from './SuggestedFollows'
@@ -31,6 +30,24 @@
+ 'atproto.com': require('../../../../assets/favicons/atproto.com.png'), + 'atproto.com': require('../../../../assets/favicons/atproto.com.png'),
+} +}
+ +
+async function resolvePds(did: string): Promise<string> {
+ if (did.startsWith('did:web:')) {
+ const host = did.split(':').slice(2).join(':')
+ const res = await fetch(`https://${host}/.well-known/did.json`)
+ if (!res.ok) throw new Error('failed to resolve did:web')
+ const doc = await res.json()
+ const pds = doc.service?.find((s: any) => s.id === '#atproto_pds')?.serviceEndpoint
+ if (pds) return pds
+ return `https://${host}`
+ }
+ const res = await fetch(`https://plc.directory/${did}`)
+ if (!res.ok) throw new Error('failed to resolve DID')
+ const doc = await res.json()
+ const pds = doc.service?.find((s: any) => s.id === '#atproto_pds')?.serviceEndpoint
+ if (!pds) throw new Error('no PDS found')
+ return pds
+}
+
+function ProfileServiceLinks({ +function ProfileServiceLinks({
+ profile, + profile,
+}: { +}: {
@@ -42,8 +59,9 @@
+ const {data: services} = useQuery({ + const {data: services} = useQuery({
+ queryKey: ['profile-services', profile.did], + queryKey: ['profile-services', profile.did],
+ queryFn: async () => { + queryFn: async () => {
+ const pds = await resolvePds(profile.did)
+ const res = await fetch( + const res = await fetch(
+ `${BSKY_SERVICE}/xrpc/com.atproto.repo.describeRepo?repo=${encodeURIComponent(profile.did)}`, + `${pds}/xrpc/com.atproto.repo.describeRepo?repo=${encodeURIComponent(profile.did)}`,
+ ) + )
+ if (!res.ok) throw new Error('failed') + if (!res.ok) throw new Error('failed')
+ const data = await res.json() + const data = await res.json()
@@ -105,7 +123,7 @@
interface Props { interface Props {
profile: AppBskyActorDefs.ProfileViewDetailed profile: AppBskyActorDefs.ProfileViewDetailed
@@ -151,6 +232,7 @@ @@ -151,6 +250,7 @@
{!isPlaceholderProfile && !isBlockedUser && ( {!isPlaceholderProfile && !isBlockedUser && (
<View style={a.gap_md}> <View style={a.gap_md}>
<ProfileHeaderMetrics profile={profile} /> <ProfileHeaderMetrics profile={profile} />

View File

@@ -0,0 +1,60 @@
--- a/src/view/com/auth/SplashScreen.tsx
+++ b/src/view/com/auth/SplashScreen.tsx
@@ -2,6 +2,7 @@
import {Image as RNImage, View} from 'react-native'
import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'
import {Image} from 'expo-image'
+import {useVideoPlayer, VideoView} from 'expo-video'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
@@ -14,10 +15,13 @@
import splashImagePointer from '../../../../assets/splash/illustration-mobile.png'
// @ts-ignore
import darkSplashImagePointer from '../../../../assets/splash/illustration-mobile-dark.png'
+// @ts-ignore
+import splashVideoPointer from '../../../../assets/splash/illustration-mobile.mp4'
const splashImageUri = RNImage.resolveAssetSource(splashImagePointer).uri
const darkSplashImageUri = RNImage.resolveAssetSource(
darkSplashImagePointer,
).uri
+const splashVideoUri = RNImage.resolveAssetSource(splashVideoPointer).uri
export const SplashScreen = ({
onPressSignin,
@@ -52,13 +56,30 @@
}
}, [t, isDarkMode])
+ const player = useVideoPlayer(splashVideoUri, p => {
+ p.loop = true
+ p.muted = true
+ p.play()
+ })
+
return (
<>
- <Image
- accessibilityIgnoresInvertColors
- source={{uri: isDarkMode ? darkSplashImageUri : splashImageUri}}
- style={[a.absolute, a.inset_0]}
- />
+ {isDarkMode ? (
+ <Image
+ accessibilityIgnoresInvertColors
+ source={{uri: darkSplashImageUri}}
+ style={[a.absolute, a.inset_0]}
+ />
+ ) : (
+ <VideoView
+ player={player}
+ style={[a.absolute, a.inset_0]}
+ contentFit="cover"
+ nativeControls={false}
+ allowsFullscreen={false}
+ allowsPictureInPicture={false}
+ />
+ )}
<Animated.View
entering={FadeIn.duration(90)}

View File

@@ -3,7 +3,6 @@ import {Pressable, View} from 'react-native'
import {type AppBskyActorDefs} from '@atproto/api' import {type AppBskyActorDefs} from '@atproto/api'
import {useQuery} from '@tanstack/react-query' import {useQuery} from '@tanstack/react-query'
import {BSKY_SERVICE} from '#/lib/constants'
import {useOpenLink} from '#/lib/hooks/useOpenLink' import {useOpenLink} from '#/lib/hooks/useOpenLink'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
@@ -66,6 +65,26 @@ const SERVICE_CONFIG: Record<
}, },
} }
// --- PDS Resolution ---
async function resolvePds(did: string): Promise<string> {
if (did.startsWith('did:web:')) {
const host = did.split(':').slice(2).join(':')
const res = await fetch(`https://${host}/.well-known/did.json`)
if (!res.ok) throw new Error('failed to resolve did:web')
const doc = await res.json()
const pds = doc.service?.find((s: any) => s.id === '#atproto_pds')?.serviceEndpoint
if (pds) return pds
return `https://${host}`
}
const res = await fetch(`https://plc.directory/${did}`)
if (!res.ok) throw new Error('failed to resolve DID')
const doc = await res.json()
const pds = doc.service?.find((s: any) => s.id === '#atproto_pds')?.serviceEndpoint
if (!pds) throw new Error('no PDS found')
return pds
}
// --- Component --- // --- Component ---
export function ProfileAtLinks({ export function ProfileAtLinks({
@@ -79,8 +98,9 @@ export function ProfileAtLinks({
const {data: linkData} = useQuery({ const {data: linkData} = useQuery({
queryKey: ['at-links', profile.did], queryKey: ['at-links', profile.did],
queryFn: async () => { queryFn: async () => {
const pds = await resolvePds(profile.did)
const res = await fetch( const res = await fetch(
`${BSKY_SERVICE}/xrpc/com.atproto.repo.getRecord?repo=${encodeURIComponent(profile.did)}&collection=ai.syui.at.link&rkey=self`, `${pds}/xrpc/com.atproto.repo.getRecord?repo=${encodeURIComponent(profile.did)}&collection=ai.syui.at.link&rkey=self`,
) )
if (!res.ok) throw new Error('not found') if (!res.ok) throw new Error('not found')
const json = await res.json() const json = await res.json()

View File

@@ -51,6 +51,7 @@ PATCH_FILES_IOS=(
"041-social-app-ios-splash-signin-button.patch" "041-social-app-ios-splash-signin-button.patch"
"042-social-app-ios-at-links.patch" "042-social-app-ios-at-links.patch"
"043-social-app-ios-rightnav-links.patch" "043-social-app-ios-rightnav-links.patch"
"044-social-app-ios-splash-video.patch"
) )
function ios-env() { function ios-env() {
@@ -186,6 +187,12 @@ function ios-copy-new-files() {
echo "✅ Copied AppInfo.tsx" echo "✅ Copied AppInfo.tsx"
fi fi
# Copy splash video
if [ -f "$d/ios/assets/splash/illustration-mobile.mp4" ]; then
cp "$d/ios/assets/splash/illustration-mobile.mp4" "$target_dir/assets/splash/illustration-mobile.mp4"
echo "✅ Copied splash video (illustration-mobile.mp4)"
fi
# Copy ProfileAtLinks.tsx # Copy ProfileAtLinks.tsx
if [ -f "$patching_dir/ProfileAtLinks.tsx" ]; then if [ -f "$patching_dir/ProfileAtLinks.tsx" ]; then
cp "$patching_dir/ProfileAtLinks.tsx" "$target_dir/src/screens/Profile/Header/ProfileAtLinks.tsx" cp "$patching_dir/ProfileAtLinks.tsx" "$target_dir/src/screens/Profile/Header/ProfileAtLinks.tsx"