Add error boundary and ATProto Embed
This commit is contained in:
@@ -165,6 +165,7 @@
|
||||
"react-avatar-editor": "^13.0.0",
|
||||
"react-compiler-runtime": "file:./lib/react-compiler-runtime",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-error-boundary": "^4.0.13",
|
||||
"react-keyed-flatten-children": "^3.0.0",
|
||||
"react-native": "0.74.1",
|
||||
"react-native-compressor": "^1.8.24",
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {AtUri} from '@atproto/api'
|
||||
import {z} from 'zod'
|
||||
|
||||
import {usePostQuery} from '#/state/queries/post'
|
||||
import {useProfileQuery} from '#/state/queries/profile'
|
||||
import {useResolveDidQuery} from '#/state/queries/resolve-uri'
|
||||
import {Post as PostInner} from '#/view/com/post/Post'
|
||||
import {ProfileCardWithFollowBtn} from '#/view/com/profile/ProfileCard'
|
||||
import {Text} from '#/components/Typography'
|
||||
|
||||
const embedProps = z.object({
|
||||
uri: z.string(),
|
||||
})
|
||||
|
||||
export type ProfileCardProps = z.infer<typeof embedProps>
|
||||
|
||||
export function Embed(props: React.PropsWithChildren<ProfileCardProps>) {
|
||||
const propsParsed = embedProps.parse(props)
|
||||
const urip = new AtUri(propsParsed.uri)
|
||||
console.log(urip)
|
||||
|
||||
if (!urip.pathname || urip.pathname === '/') {
|
||||
return <Actor actor={urip.host} />
|
||||
}
|
||||
if (urip.collection === 'app.bsky.feed.post') {
|
||||
return <Post uri={urip.toString()} />
|
||||
}
|
||||
return <Unknown urip={urip} />
|
||||
}
|
||||
|
||||
function Actor({actor}: {actor: string}) {
|
||||
const {data: did} = useResolveDidQuery(actor)
|
||||
const {data: profile} = useProfileQuery({did})
|
||||
|
||||
if (profile) {
|
||||
return <ProfileCardWithFollowBtn noBg noBorder profile={profile} />
|
||||
}
|
||||
// TODO error, loading
|
||||
return <View />
|
||||
}
|
||||
|
||||
function Post({uri}: {uri: string}) {
|
||||
const {data: post} = usePostQuery(uri)
|
||||
if (post) {
|
||||
return <PostInner post={post} hideTopBorder />
|
||||
}
|
||||
// TODO error, loading
|
||||
return <View />
|
||||
}
|
||||
|
||||
function Unknown({urip}: {urip: AtUri}) {
|
||||
return (
|
||||
<View style={{paddingVertical: 10, paddingHorizontal: 15}}>
|
||||
<Text>Unsupported record type: {urip.collection}</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -1,7 +1,12 @@
|
||||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {ErrorBoundary} from 'react-error-boundary'
|
||||
import {ZodError} from 'zod'
|
||||
|
||||
import {Text} from '#/components/Typography'
|
||||
import type {AppComNode} from '../types'
|
||||
import {Box} from './Box'
|
||||
import {Embed} from './Embed'
|
||||
import {Expandable} from './Expandable'
|
||||
import {Label} from './Label'
|
||||
import {Stack} from './Stack'
|
||||
@@ -9,6 +14,7 @@ import {Tabs} from './Tabs'
|
||||
|
||||
export const VOCAB: Record<string, React.ComponentType<any>> = {
|
||||
Box,
|
||||
Embed,
|
||||
Expandable,
|
||||
Label,
|
||||
Stack,
|
||||
@@ -22,12 +28,25 @@ export function AppComponent({node}: {node: AppComNode}) {
|
||||
return <></>
|
||||
}
|
||||
return (
|
||||
<Com {...node.props}>
|
||||
{node.children?.length
|
||||
? node.children.map((child, i) => (
|
||||
<AppComponent key={child.key || String(i)} node={child} />
|
||||
))
|
||||
: null}
|
||||
</Com>
|
||||
<ErrorBoundary fallbackRender={fallbackRender}>
|
||||
<Com {...node.props}>
|
||||
{node.children?.length
|
||||
? node.children.map((child, i) => (
|
||||
<AppComponent key={child.key || String(i)} node={child} />
|
||||
))
|
||||
: null}
|
||||
</Com>
|
||||
</ErrorBoundary>
|
||||
)
|
||||
}
|
||||
function fallbackRender({error}: {error: Error}) {
|
||||
const msg =
|
||||
error instanceof ZodError
|
||||
? `${error.issues[0].path.join('.')}: ${error.issues[0].message}`
|
||||
: error.toString()
|
||||
return (
|
||||
<View>
|
||||
<Text>{msg}</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -74,7 +74,39 @@ const DEFAULT_AC = h('Stack', {gap: 10}, [
|
||||
h('Label', {text: 'Display TODO'}),
|
||||
h('Label', {text: 'Inputs TODO'}),
|
||||
h('Label', {text: 'Forms TODO'}),
|
||||
h('Label', {text: 'ATProto TODO'}),
|
||||
h('Stack', {gap: 10, pad: {t: 20}}, [
|
||||
h('Box', {pad: {x: 10}}, [
|
||||
h('Label', {text: 'Embed (Actor)', size: 10, weight: 'bold'}),
|
||||
]),
|
||||
h('Box', {border: 'secondary', corner: 8}, [
|
||||
h('Embed', {uri: 'bsky.app'}),
|
||||
]),
|
||||
h('Box', {border: 'secondary', corner: 8}, [
|
||||
h('Embed', {uri: 'at://atproto.com/'}),
|
||||
]),
|
||||
h('Box', {border: 'secondary', corner: 8}, [
|
||||
h('Embed', {uri: 'at://pfrazee.com'}),
|
||||
]),
|
||||
h('Box', {pad: {x: 10}}, [
|
||||
h('Label', {text: 'Embed (Post)', size: 10, weight: 'bold'}),
|
||||
]),
|
||||
h('Box', {border: 'secondary', corner: 8}, [
|
||||
h('Embed', {uri: 'at://pfrazee.com/app.bsky.feed.post/3ku7fbojcqs25'}),
|
||||
]),
|
||||
h('Box', {border: 'secondary', corner: 8}, [
|
||||
h('Embed', {uri: 'at://bsky.app/app.bsky.feed.post/3ku73zs755e27'}),
|
||||
]),
|
||||
h('Box', {pad: {x: 10}}, [
|
||||
h('Label', {
|
||||
text: 'Embed (Unsupported record type)',
|
||||
size: 10,
|
||||
weight: 'bold',
|
||||
}),
|
||||
]),
|
||||
h('Box', {border: 'secondary', corner: 8}, [
|
||||
h('Embed', {uri: 'at://pfrazee.com/com.example.unknown/123'}),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
])
|
||||
|
||||
|
||||
@@ -18820,6 +18820,13 @@ react-dom@^18.2.0:
|
||||
loose-envify "^1.1.0"
|
||||
scheduler "^0.23.0"
|
||||
|
||||
react-error-boundary@^4.0.13:
|
||||
version "4.0.13"
|
||||
resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-4.0.13.tgz#80386b7b27b1131c5fbb7368b8c0d983354c7947"
|
||||
integrity sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
|
||||
react-error-overlay@^6.0.11:
|
||||
version "6.0.11"
|
||||
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb"
|
||||
|
||||
Reference in New Issue
Block a user