Add error boundary and ATProto Embed

This commit is contained in:
Paul Frazee
2024-06-07 08:11:29 -07:00
committed by Dan Abramov
parent 18b7c466cf
commit 5e14462a23
5 changed files with 126 additions and 8 deletions
+1
View File
@@ -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>
)
}
+26 -7
View File
@@ -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>
)
}
+33 -1
View File
@@ -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'}),
]),
]),
]),
])
+7
View File
@@ -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"