From 3349174bbdcf281bfb86e73f48addf893e40585f Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Sat, 6 Jul 2024 04:58:12 +0100 Subject: [PATCH] Start moving code around --- sdui/server/src/App.js | 132 ++++++++++++++++ src/components/appcom/AppCom.tsx | 27 ++-- src/components/appcom/vocabulary/index.tsx | 36 +---- src/view/screens/DebugAppcom.tsx | 166 +-------------------- 4 files changed, 156 insertions(+), 205 deletions(-) diff --git a/sdui/server/src/App.js b/sdui/server/src/App.js index 68c10a2d41..051c60bd70 100644 --- a/sdui/server/src/App.js +++ b/sdui/server/src/App.js @@ -5,3 +5,135 @@ import {Text} from './client.js' export default async function App() { return hello } + +// TODO +// const DEFAULT_AC = h('Stack', {gap: 10}, [ +// h('Label', { +// size: 36, +// lineHeight: 1.2, +// weight: 'bold', +// text: 'Hello, world!', +// }), +// h('Label', { +// lineHeight: 1.2, +// text: 'This is the initial version of a fantastic new feature of the AT Protocol called "application components."', +// }), +// h('Tabs', {labels: ['Layout', 'Display', 'Inputs', 'Forms', 'ATProto']}, [ +// h('Stack', {gap: 10, pad: {t: 20}}, [ +// h('Box', {pad: {x: 10}}, [ +// h('Label', {text: 'Stack', size: 10, weight: 'bold'}), +// ]), +// h('Box', {border: 'default', corner: 10, pad: {x: 2, y: 6}}, [ +// h( +// 'Stack', +// { +// direction: 'row', +// align: 'center', +// gap: 10, +// pad: {x: 10}, +// }, +// [ +// h('Label', {text: 'One'}), +// h('Label', {text: 'Two', color: 'positive'}), +// h('Box', {border: 'default', corner: 4, pad: 10}, [ +// {type: 'Label', props: {text: 'Three'}}, +// ]), +// h('Box', {background: 'secondary', corner: 4, pad: 10}, [ +// {type: 'Label', props: {text: 'Four'}}, +// ]), +// h('Label', {text: 'Five', color: 'secondary'}), +// ], +// ), +// ]), +// h('Box', {pad: {x: 10}}, [ +// h('Label', {text: 'Box', size: 10, weight: 'bold'}), +// ]), +// h('Box', {border: 'default', corner: 10, pad: {x: 10, y: 14}}, [ +// h('Label', { +// text: 'You can use the Box element as somewhat similar to a div.', +// }), +// h('Label', {text: 'Its children flow vertically with no gap.'}), +// h('Label', { +// text: 'What it offers is styling -- border, corner radius, background, and padding.', +// }), +// h('Label', { +// text: 'If you want to control layout then you use a Stack, then if you want styling you use a Box.', +// }), +// h('Label', { +// text: 'Boxes also make good neutral containers.', +// }), +// ]), +// h('Box', {pad: {x: 10}}, [ +// h('Label', {text: 'Expandable', size: 10, weight: 'bold'}), +// ]), +// h('Box', {border: 'default', corner: 10, pad: 6}, [ +// h('Expandable', {label: 'Expandable'}, [h('Label', {text: 'Content'})]), +// ]), +// ]), +// h('Label', {text: 'Display TODO'}), +// h('Label', {text: 'Inputs TODO'}), +// h('Label', {text: 'Forms TODO'}), +// h('Stack', {gap: 10, pad: {t: 20}}, [ +// h('Box', {pad: {x: 10}}, [ +// h('Label', {text: 'Avatar', size: 10, weight: 'bold'}), +// ]), +// h('Box', {border: 'secondary', corner: 8, pad: {x: 16, y: 12}}, [ +// h('Stack', {direction: 'row', gap: 10}, [ +// h('Avatar', {uri: 'bsky.app'}), +// h('Avatar', {uri: 'at://atproto.com'}), +// h('Avatar', {uri: 'at://pfrazee.com/'}), +// ]), +// ]), +// h('Box', {pad: {x: 10}}, [ +// h('Label', {text: 'ActorLabel', size: 10, weight: 'bold'}), +// ]), +// h('Box', {border: 'secondary', corner: 8, pad: {x: 16, y: 12}}, [ +// h('Stack', {gap: 10}, [ +// h('Stack', {direction: 'row', gap: 8}, [ +// h('Label', {weight: 'bold', text: 'Display Name:'}), +// h('ActorLabel', {uri: 'bsky.app', field: 'displayName'}), +// ]), +// h('Stack', {direction: 'row', gap: 8}, [ +// h('Label', {weight: 'bold', text: 'Handle:'}), +// h('ActorLabel', {uri: 'bsky.app', field: 'handle'}), +// ]), +// h('Stack', {direction: 'row', gap: 8}, [ +// h('Label', {weight: 'bold', text: 'Description:'}), +// h('ActorLabel', {uri: 'bsky.app', field: 'description'}), +// ]), +// ]), +// ]), +// 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'}), +// ]), +// ]), +// ]), +// ]) diff --git a/src/components/appcom/AppCom.tsx b/src/components/appcom/AppCom.tsx index 38a604b244..1bac9ee1eb 100644 --- a/src/components/appcom/AppCom.tsx +++ b/src/components/appcom/AppCom.tsx @@ -1,18 +1,13 @@ import React from 'react' import {View} from 'react-native' +import {ErrorBoundary} from 'react-error-boundary' +import {ZodError} from 'zod' import {atoms as a, useTheme} from '#/alf' import {Text} from '../Typography' -import type {AppComNode} from './types' import {AppComponent} from './vocabulary' -export function AppComponentRegion({ - tree, - origin, -}: { - tree: AppComNode - origin: string -}) { +export function AppComponentRegion({origin}: {origin: string}) { const t = useTheme() return ( @@ -36,8 +31,22 @@ export function AppComponentRegion({ - + + + ) } + +function fallbackRender({error}: {error: Error}) { + const msg = + error instanceof ZodError + ? `${error.issues[0].path.join('.')}: ${error.issues[0].message}` + : error.toString() + return ( + + {msg} + + ) +} diff --git a/src/components/appcom/vocabulary/index.tsx b/src/components/appcom/vocabulary/index.tsx index e9e1aaaf8e..887cd78fe9 100644 --- a/src/components/appcom/vocabulary/index.tsx +++ b/src/components/appcom/vocabulary/index.tsx @@ -1,10 +1,6 @@ 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 {ActorLabel} from './ActorLabel' import {Avatar} from './Avatar' import {Box} from './Box' @@ -14,6 +10,7 @@ import {Label} from './Label' import {Stack} from './Stack' import {Tabs} from './Tabs' +// TODO export const VOCAB: Record> = { ActorLabel, Avatar, @@ -25,32 +22,7 @@ export const VOCAB: Record> = { Tabs, } -export function AppComponent({node}: {node: AppComNode}) { - const Com = VOCAB[node.type] - if (!Com) { - console.error('Unknown component:', node.type) - return <> - } - return ( - - - {node.children?.length - ? node.children.map((child, i) => ( - - )) - : null} - - - ) -} -function fallbackRender({error}: {error: Error}) { - const msg = - error instanceof ZodError - ? `${error.issues[0].path.join('.')}: ${error.issues[0].message}` - : error.toString() - return ( - - {msg} - - ) +export function AppComponent({origin}: {origin: string}) { + // TODO + return {origin} } diff --git a/src/view/screens/DebugAppcom.tsx b/src/view/screens/DebugAppcom.tsx index 637f86fa08..e15c69d959 100644 --- a/src/view/screens/DebugAppcom.tsx +++ b/src/view/screens/DebugAppcom.tsx @@ -5,159 +5,14 @@ import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types' import {CenteredView, ScrollView} from '#/view/com/util/Views' import {atoms as a, useTheme} from '#/alf' import {AppComponentRegion} from '#/components/appcom/AppCom' -import * as TextField from '#/components/forms/TextField' import {Text} from '#/components/Typography' -const DEFAULT_AC = h('Stack', {gap: 10}, [ - h('Label', { - size: 36, - lineHeight: 1.2, - weight: 'bold', - text: 'Hello, world!', - }), - h('Label', { - lineHeight: 1.2, - text: 'This is the initial version of a fantastic new feature of the AT Protocol called "application components."', - }), - h('Tabs', {labels: ['Layout', 'Display', 'Inputs', 'Forms', 'ATProto']}, [ - h('Stack', {gap: 10, pad: {t: 20}}, [ - h('Box', {pad: {x: 10}}, [ - h('Label', {text: 'Stack', size: 10, weight: 'bold'}), - ]), - h('Box', {border: 'default', corner: 10, pad: {x: 2, y: 6}}, [ - h( - 'Stack', - { - direction: 'row', - align: 'center', - gap: 10, - pad: {x: 10}, - }, - [ - h('Label', {text: 'One'}), - h('Label', {text: 'Two', color: 'positive'}), - h('Box', {border: 'default', corner: 4, pad: 10}, [ - {type: 'Label', props: {text: 'Three'}}, - ]), - h('Box', {background: 'secondary', corner: 4, pad: 10}, [ - {type: 'Label', props: {text: 'Four'}}, - ]), - h('Label', {text: 'Five', color: 'secondary'}), - ], - ), - ]), - h('Box', {pad: {x: 10}}, [ - h('Label', {text: 'Box', size: 10, weight: 'bold'}), - ]), - h('Box', {border: 'default', corner: 10, pad: {x: 10, y: 14}}, [ - h('Label', { - text: 'You can use the Box element as somewhat similar to a div.', - }), - h('Label', {text: 'Its children flow vertically with no gap.'}), - h('Label', { - text: 'What it offers is styling -- border, corner radius, background, and padding.', - }), - h('Label', { - text: 'If you want to control layout then you use a Stack, then if you want styling you use a Box.', - }), - h('Label', { - text: 'Boxes also make good neutral containers.', - }), - ]), - h('Box', {pad: {x: 10}}, [ - h('Label', {text: 'Expandable', size: 10, weight: 'bold'}), - ]), - h('Box', {border: 'default', corner: 10, pad: 6}, [ - h('Expandable', {label: 'Expandable'}, [h('Label', {text: 'Content'})]), - ]), - ]), - h('Label', {text: 'Display TODO'}), - h('Label', {text: 'Inputs TODO'}), - h('Label', {text: 'Forms TODO'}), - h('Stack', {gap: 10, pad: {t: 20}}, [ - h('Box', {pad: {x: 10}}, [ - h('Label', {text: 'Avatar', size: 10, weight: 'bold'}), - ]), - h('Box', {border: 'secondary', corner: 8, pad: {x: 16, y: 12}}, [ - h('Stack', {direction: 'row', gap: 10}, [ - h('Avatar', {uri: 'bsky.app'}), - h('Avatar', {uri: 'at://atproto.com'}), - h('Avatar', {uri: 'at://pfrazee.com/'}), - ]), - ]), - h('Box', {pad: {x: 10}}, [ - h('Label', {text: 'ActorLabel', size: 10, weight: 'bold'}), - ]), - h('Box', {border: 'secondary', corner: 8, pad: {x: 16, y: 12}}, [ - h('Stack', {gap: 10}, [ - h('Stack', {direction: 'row', gap: 8}, [ - h('Label', {weight: 'bold', text: 'Display Name:'}), - h('ActorLabel', {uri: 'bsky.app', field: 'displayName'}), - ]), - h('Stack', {direction: 'row', gap: 8}, [ - h('Label', {weight: 'bold', text: 'Handle:'}), - h('ActorLabel', {uri: 'bsky.app', field: 'handle'}), - ]), - h('Stack', {direction: 'row', gap: 8}, [ - h('Label', {weight: 'bold', text: 'Description:'}), - h('ActorLabel', {uri: 'bsky.app', field: 'description'}), - ]), - ]), - ]), - 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'}), - ]), - ]), - ]), -]) - export const DebugAppcomScreen = ({}: NativeStackScreenProps< CommonNavigatorParams, 'DebugAppcom' >) => { const t = useTheme() - const [acJson, setAcJson] = React.useState( - JSON.stringify(DEFAULT_AC, null, 2), - ) - const [acObj, setAcObj] = React.useState(undefined) - const [error, setError] = React.useState('') - - React.useEffect(() => { - try { - setAcObj(JSON.parse(acJson)) - setError('') - } catch (e: any) { - setError(e.toString()) - } - }, [acJson, setAcObj, setError]) + const error = '' // TODO return ( @@ -166,15 +21,6 @@ export const DebugAppcomScreen = ({}: NativeStackScreenProps< Application components - Application JSON component - - {error && ( - {acObj && } + ) } - -function h(type: string, props?: any | Array, children?: Array) { - return { - type, - props: Array.isArray(props) ? undefined : props, - children: Array.isArray(props) ? props : children, - } -}