diff options
author | Paul Frazee <pfrazee@gmail.com> | 2022-07-19 15:37:24 -0500 |
---|---|---|
committer | Paul Frazee <pfrazee@gmail.com> | 2022-07-19 15:37:24 -0500 |
commit | dc55f580049d284c6e01271e3885c4fa23a8f458 (patch) | |
tree | 64112d4525410ef3ca8553901af81f5df1e216da /src/view | |
parent | 6b32698b3e020e5910c92b72a1677e7cd56287d6 (diff) | |
download | voidsky-dc55f580049d284c6e01271e3885c4fa23a8f458.tar.zst |
Replace mobx-state-tree with mobx and get a basic home feed rendering
Diffstat (limited to 'src/view')
-rw-r--r-- | src/view/com/Feed.tsx | 17 | ||||
-rw-r--r-- | src/view/com/FeedItem.tsx | 104 | ||||
-rw-r--r-- | src/view/screens/Home.tsx | 25 | ||||
-rw-r--r-- | src/view/screens/Login.tsx | 32 | ||||
-rw-r--r-- | src/view/screens/Signup.tsx | 14 |
5 files changed, 159 insertions, 33 deletions
diff --git a/src/view/com/Feed.tsx b/src/view/com/Feed.tsx new file mode 100644 index 000000000..2cba0610a --- /dev/null +++ b/src/view/com/Feed.tsx @@ -0,0 +1,17 @@ +import React from 'react' +import {observer} from 'mobx-react-lite' +import {Text, View} from 'react-native' +import {FeedViewModel} from '../../state/models/feed-view' +import {FeedItem} from './FeedItem' + +export const Feed = observer(function Feed({feed}: {feed: FeedViewModel}) { + return ( + <View> + {feed.isLoading && <Text>Loading...</Text>} + {feed.hasError && <Text>{feed.error}</Text>} + {feed.hasContent && + feed.feed.map(item => <FeedItem key={item.key} item={item} />)} + {feed.isEmpty && <Text>This feed is empty!</Text>} + </View> + ) +}) diff --git a/src/view/com/FeedItem.tsx b/src/view/com/FeedItem.tsx new file mode 100644 index 000000000..8f838d5df --- /dev/null +++ b/src/view/com/FeedItem.tsx @@ -0,0 +1,104 @@ +import React from 'react' +import {observer} from 'mobx-react-lite' +import {Text, Image, ImageSourcePropType, StyleSheet, View} from 'react-native' +import {bsky} from '@adxp/mock-api' +import moment from 'moment' +import {FeedViewItemModel} from '../../state/models/feed-view' + +const IMAGES: Record<string, ImageSourcePropType> = { + 'alice.com': require('../../assets/alice.jpg'), + 'bob.com': require('../../assets/bob.jpg'), + 'carla.com': require('../../assets/carla.jpg'), +} + +export const FeedItem = observer(function FeedItem({ + item, +}: { + item: FeedViewItemModel +}) { + const record = item.record as unknown as bsky.Post.Record + return ( + <View style={styles.outer}> + {item.repostedBy && ( + <Text style={styles.repostedBy}> + Reposted by {item.repostedBy.displayName} + </Text> + )} + <View style={styles.layout}> + <View style={styles.layoutAvi}> + <Image + style={styles.avi} + source={IMAGES[item.author.name] || IMAGES['alice.com']} + /> + </View> + <View style={styles.layoutContent}> + <View style={styles.meta}> + <Text style={[styles.metaItem, styles.metaDisplayName]}> + {item.author.displayName} + </Text> + <Text style={[styles.metaItem, styles.metaName]}> + @{item.author.name} + </Text> + <Text style={[styles.metaItem, styles.metaDate]}> + · {moment(item.indexedAt).fromNow(true)} + </Text> + </View> + <Text style={styles.postText}>{record.text}</Text> + </View> + </View> + </View> + ) +}) + +const styles = StyleSheet.create({ + outer: { + borderTopWidth: 1, + borderTopColor: '#e8e8e8', + backgroundColor: '#fff', + padding: 10, + }, + repostedBy: { + paddingLeft: 70, + color: 'gray', + fontWeight: 'bold', + fontSize: 13, + }, + layout: { + flexDirection: 'row', + }, + layoutAvi: { + width: 70, + }, + avi: { + width: 60, + height: 60, + borderRadius: 30, + resizeMode: 'cover', + }, + layoutContent: { + flex: 1, + }, + meta: { + flexDirection: 'row', + paddingTop: 2, + paddingBottom: 4, + }, + metaItem: { + paddingRight: 5, + }, + metaDisplayName: { + fontSize: 15, + fontWeight: 'bold', + }, + metaName: { + fontSize: 14, + color: 'gray', + }, + metaDate: { + fontSize: 14, + color: 'gray', + }, + postText: { + fontSize: 15, + }, +}) diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx index 5210d9d40..53ec44eb9 100644 --- a/src/view/screens/Home.tsx +++ b/src/view/screens/Home.tsx @@ -1,20 +1,23 @@ -import React from 'react' -import {Text, Button, View} from 'react-native' +import React, {useEffect} from 'react' +import {Text, View} from 'react-native' import {Shell} from '../shell' -import type {RootTabsScreenProps} from '../routes/types' +import {Feed} from '../com/Feed' +// import type {RootTabsScreenProps} from '../routes/types' import {useStores} from '../../state' -export function Home({navigation}: RootTabsScreenProps<'Home'>) { +export function Home(/*{navigation}: RootTabsScreenProps<'Home'>*/) { const store = useStores() + useEffect(() => { + console.log('Fetching home feed') + store.homeFeed.fetch() + }, [store.homeFeed]) return ( <Shell> - <View style={{alignItems: 'center'}}> - <Text style={{fontSize: 20, fontWeight: 'bold'}}>Home</Text> - <Button - title="Go to Jane's profile" - onPress={() => navigation.navigate('Profile', {name: 'Jane'})} - /> - <Button title="Logout" onPress={() => store.session.logout()} /> + <View> + <Text style={{fontSize: 20, fontWeight: 'bold'}}> + Hello, {store.me.displayName} ({store.me.name}) + </Text> + <Feed feed={store.homeFeed} /> </View> </Shell> ) diff --git a/src/view/screens/Login.tsx b/src/view/screens/Login.tsx index 207557369..d08a5a256 100644 --- a/src/view/screens/Login.tsx +++ b/src/view/screens/Login.tsx @@ -1,17 +1,18 @@ import React from 'react' -import {Text, Button, View, ActivityIndicator} from 'react-native' +import {Text, View} from 'react-native' import {observer} from 'mobx-react-lite' import {Shell} from '../shell' -import type {RootTabsScreenProps} from '../routes/types' -import {useStores} from '../../state' +// import type {RootTabsScreenProps} from '../routes/types' +// import {useStores} from '../../state' -export const Login = observer(({navigation}: RootTabsScreenProps<'Login'>) => { - const store = useStores() - return ( - <Shell> - <View style={{justifyContent: 'center', alignItems: 'center'}}> - <Text style={{fontSize: 20, fontWeight: 'bold'}}>Sign In</Text> - {store.session.uiError ?? <Text>{store.session.uiError}</Text>} +export const Login = observer( + (/*{navigation}: RootTabsScreenProps<'Login'>*/) => { + // const store = useStores() + return ( + <Shell> + <View style={{justifyContent: 'center', alignItems: 'center'}}> + <Text style={{fontSize: 20, fontWeight: 'bold'}}>Sign In</Text> + {/*store.session.uiError && <Text>{store.session.uiError}</Text>} {!store.session.uiIsProcessing ? ( <> <Button title="Login" onPress={() => store.session.login()} /> @@ -22,8 +23,9 @@ export const Login = observer(({navigation}: RootTabsScreenProps<'Login'>) => { </> ) : ( <ActivityIndicator /> - )} - </View> - </Shell> - ) -}) + )*/} + </View> + </Shell> + ) + }, +) diff --git a/src/view/screens/Signup.tsx b/src/view/screens/Signup.tsx index 8ca47e3ef..4a8c5df2d 100644 --- a/src/view/screens/Signup.tsx +++ b/src/view/screens/Signup.tsx @@ -1,18 +1,18 @@ import React from 'react' -import {Text, Button, View, ActivityIndicator} from 'react-native' +import {Text, View} from 'react-native' import {observer} from 'mobx-react-lite' import {Shell} from '../shell' -import type {RootTabsScreenProps} from '../routes/types' -import {useStores} from '../../state' +// import type {RootTabsScreenProps} from '../routes/types' +// import {useStores} from '../../state' export const Signup = observer( - ({navigation}: RootTabsScreenProps<'Signup'>) => { - const store = useStores() + (/*{navigation}: RootTabsScreenProps<'Signup'>*/) => { + // const store = useStores() return ( <Shell> <View style={{justifyContent: 'center', alignItems: 'center'}}> <Text style={{fontSize: 20, fontWeight: 'bold'}}>Create Account</Text> - {store.session.uiError ?? <Text>{store.session.uiError}</Text>} + {/*store.session.uiError ?? <Text>{store.session.uiError}</Text>} {!store.session.uiIsProcessing ? ( <> <Button @@ -26,7 +26,7 @@ export const Signup = observer( </> ) : ( <ActivityIndicator /> - )} + )*/} </View> </Shell> ) |