diff options
Diffstat (limited to 'src/view/screens')
25 files changed, 395 insertions, 517 deletions
diff --git a/src/view/screens/Composer.tsx b/src/view/screens/Composer.tsx new file mode 100644 index 000000000..2de84583f --- /dev/null +++ b/src/view/screens/Composer.tsx @@ -0,0 +1,43 @@ +import React, {useLayoutEffect, useRef} from 'react' +// import {Text, TouchableOpacity} from 'react-native' +// import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {Composer as ComposerComponent} from '../com/composer/Composer' +import {ScreenParams} from '../routes' + +export const Composer = ({params}: ScreenParams) => { + const {replyTo} = params + const ref = useRef<{publish: () => Promise<boolean>}>() + + // TODO + // useLayoutEffect(() => { + // navigation.setOptions({ + // headerShown: true, + // headerTitle: replyTo ? 'Reply' : 'New Post', + // headerLeft: () => ( + // <TouchableOpacity onPress={() => navigation.goBack()}> + // <FontAwesomeIcon icon="x" /> + // </TouchableOpacity> + // ), + // headerRight: () => ( + // <TouchableOpacity + // onPress={() => { + // if (!ref.current) { + // return + // } + // ref.current.publish().then( + // posted => { + // if (posted) { + // navigation.goBack() + // } + // }, + // err => console.error('Failed to create post', err), + // ) + // }}> + // <Text>Post</Text> + // </TouchableOpacity> + // ), + // }) + // }, [navigation, replyTo, ref]) + + return <ComposerComponent ref={ref} replyTo={replyTo} /> +} diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx new file mode 100644 index 000000000..a94ffd2f7 --- /dev/null +++ b/src/view/screens/Home.tsx @@ -0,0 +1,65 @@ +import React, {useState, useEffect, useLayoutEffect} from 'react' +import {Image, StyleSheet, TouchableOpacity, View} from 'react-native' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {Feed} from '../com/feed/Feed' +import {useStores} from '../../state' +import {useLoadEffect} from '../lib/navigation' +import {AVIS} from '../lib/assets' +import {ScreenParams} from '../routes' + +export function Home({params}: ScreenParams) { + const [hasSetup, setHasSetup] = useState<boolean>(false) + const store = useStores() + useLoadEffect(() => { + store.nav.setTitle('Home') + console.log('Fetching home feed') + store.homeFeed.setup().then(() => setHasSetup(true)) + }, [store.nav, store.homeFeed]) + + // TODO + // useEffect(() => { + // return navigation.addListener('focus', () => { + // if (hasSetup) { + // console.log('Updating home feed') + // store.homeFeed.update() + // } + // }) + // }, [navigation, store.homeFeed, hasSetup]) + + // TODO + // useLayoutEffect(() => { + // navigation.setOptions({ + // headerShown: true, + // headerTitle: 'V I B E', + // headerLeft: () => ( + // <TouchableOpacity + // onPress={() => navigation.push('Profile', {name: 'alice.com'})}> + // <Image source={AVIS['alice.com']} style={styles.avi} /> + // </TouchableOpacity> + // ), + // headerRight: () => ( + // <TouchableOpacity + // onPress={() => { + // navigation.push('Composer', {}) + // }}> + // <FontAwesomeIcon icon="plus" style={{color: '#006bf7'}} /> + // </TouchableOpacity> + // ), + // }) + // }, [navigation]) + + return ( + <View> + <Feed feed={store.homeFeed} /> + </View> + ) +} + +const styles = StyleSheet.create({ + avi: { + width: 20, + height: 20, + borderRadius: 10, + resizeMode: 'cover', + }, +}) diff --git a/src/view/screens/tabroots/Login.tsx b/src/view/screens/Login.tsx index a5f670bdd..0857687ab 100644 --- a/src/view/screens/tabroots/Login.tsx +++ b/src/view/screens/Login.tsx @@ -1,18 +1,15 @@ import React from 'react' 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' 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>} + <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()} /> @@ -24,8 +21,7 @@ export const Login = observer( ) : ( <ActivityIndicator /> )*/} - </View> - </Shell> + </View> ) }, ) diff --git a/src/view/screens/NotFound.tsx b/src/view/screens/NotFound.tsx new file mode 100644 index 000000000..2483da1e6 --- /dev/null +++ b/src/view/screens/NotFound.tsx @@ -0,0 +1,13 @@ +import React from 'react' +import {Text, Button, View} from 'react-native' +import {useStores} from '../../state' + +export const NotFound = () => { + const stores = useStores() + return ( + <View style={{justifyContent: 'center', alignItems: 'center'}}> + <Text style={{fontSize: 20, fontWeight: 'bold'}}>Page not found</Text> + <Button title="Home" onPress={() => stores.nav.navigate('/')} /> + </View> + ) +} diff --git a/src/view/screens/Notifications.tsx b/src/view/screens/Notifications.tsx new file mode 100644 index 000000000..7ebc8a7ce --- /dev/null +++ b/src/view/screens/Notifications.tsx @@ -0,0 +1,65 @@ +import React, {useState, useEffect, useLayoutEffect} from 'react' +import {Image, StyleSheet, TouchableOpacity, View} from 'react-native' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {Feed} from '../com/notifications/Feed' +import {useStores} from '../../state' +import {AVIS} from '../lib/assets' +import {ScreenParams} from '../routes' +import {useLoadEffect} from '../lib/navigation' + +export const Notifications = ({params}: ScreenParams) => { + const [hasSetup, setHasSetup] = useState<boolean>(false) + const store = useStores() + useLoadEffect(() => { + store.nav.setTitle('Notifications') + console.log('Fetching notifications feed') + store.notesFeed.setup().then(() => setHasSetup(true)) + }, [store.notesFeed]) + + // TODO + // useEffect(() => { + // return navigation.addListener('focus', () => { + // if (hasSetup) { + // console.log('Updating notifications feed') + // store.notesFeed.update() + // } + // }) + // }, [navigation, store.notesFeed, hasSetup]) + + // TODO + // useLayoutEffect(() => { + // navigation.setOptions({ + // headerShown: true, + // headerTitle: 'Notifications', + // headerLeft: () => ( + // <TouchableOpacity + // onPress={() => navigation.push('Profile', {name: 'alice.com'})}> + // <Image source={AVIS['alice.com']} style={styles.avi} /> + // </TouchableOpacity> + // ), + // headerRight: () => ( + // <TouchableOpacity + // onPress={() => { + // navigation.push('Composer', {}) + // }}> + // <FontAwesomeIcon icon="plus" style={{color: '#006bf7'}} /> + // </TouchableOpacity> + // ), + // }) + // }, [navigation]) + + return ( + <View> + <Feed view={store.notesFeed} /> + </View> + ) +} + +const styles = StyleSheet.create({ + avi: { + width: 20, + height: 20, + borderRadius: 10, + resizeMode: 'cover', + }, +}) diff --git a/src/view/screens/PostLikedBy.tsx b/src/view/screens/PostLikedBy.tsx new file mode 100644 index 000000000..92fae30ad --- /dev/null +++ b/src/view/screens/PostLikedBy.tsx @@ -0,0 +1,26 @@ +import React, {useLayoutEffect} from 'react' +import {TouchableOpacity} from 'react-native' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {makeRecordUri} from '../lib/strings' +import {PostLikedBy as PostLikedByComponent} from '../com/post-thread/PostLikedBy' +import {ScreenParams} from '../routes' + +export const PostLikedBy = ({params}: ScreenParams) => { + const {name, recordKey} = params + const uri = makeRecordUri(name, 'blueskyweb.xyz:Posts', recordKey) + + // TODO + // useLayoutEffect(() => { + // navigation.setOptions({ + // headerShown: true, + // headerTitle: 'Liked By', + // headerLeft: () => ( + // <TouchableOpacity onPress={() => navigation.goBack()}> + // <FontAwesomeIcon icon="arrow-left" /> + // </TouchableOpacity> + // ), + // }) + // }, [navigation]) + + return <PostLikedByComponent uri={uri} /> +} diff --git a/src/view/screens/PostRepostedBy.tsx b/src/view/screens/PostRepostedBy.tsx new file mode 100644 index 000000000..81014a7c7 --- /dev/null +++ b/src/view/screens/PostRepostedBy.tsx @@ -0,0 +1,26 @@ +import React, {useLayoutEffect} from 'react' +import {TouchableOpacity} from 'react-native' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {makeRecordUri} from '../lib/strings' +import {PostRepostedBy as PostRepostedByComponent} from '../com/post-thread/PostRepostedBy' +import {ScreenParams} from '../routes' + +export const PostRepostedBy = ({params}: ScreenParams) => { + const {name, recordKey} = params + const uri = makeRecordUri(name, 'blueskyweb.xyz:Posts', recordKey) + + // TODO + // useLayoutEffect(() => { + // navigation.setOptions({ + // headerShown: true, + // headerTitle: 'Reposted By', + // headerLeft: () => ( + // <TouchableOpacity onPress={() => navigation.goBack()}> + // <FontAwesomeIcon icon="arrow-left" /> + // </TouchableOpacity> + // ), + // }) + // }, [navigation]) + + return <PostRepostedByComponent uri={uri} /> +} diff --git a/src/view/screens/PostThread.tsx b/src/view/screens/PostThread.tsx new file mode 100644 index 000000000..1003a40e1 --- /dev/null +++ b/src/view/screens/PostThread.tsx @@ -0,0 +1,32 @@ +import React, {useEffect, useLayoutEffect} from 'react' +import {TouchableOpacity} from 'react-native' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {makeRecordUri} from '../lib/strings' +import {PostThread as PostThreadComponent} from '../com/post-thread/PostThread' +import {ScreenParams} from '../routes' +import {useStores} from '../../state' +import {useLoadEffect} from '../lib/navigation' + +export const PostThread = ({params}: ScreenParams) => { + const store = useStores() + const {name, recordKey} = params + const uri = makeRecordUri(name, 'blueskyweb.xyz:Posts', recordKey) + useLoadEffect(() => { + store.nav.setTitle(`Post by ${name}`) + }, [store.nav, name]) + + // TODO + // useLayoutEffect(() => { + // navigation.setOptions({ + // headerShown: true, + // headerTitle: 'Thread', + // headerLeft: () => ( + // <TouchableOpacity onPress={() => navigation.goBack()}> + // <FontAwesomeIcon icon="arrow-left" /> + // </TouchableOpacity> + // ), + // }) + // }, [navigation]) + + return <PostThreadComponent uri={uri} /> +} diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx new file mode 100644 index 000000000..84ff63f5a --- /dev/null +++ b/src/view/screens/Profile.tsx @@ -0,0 +1,58 @@ +import React, {useState, useEffect} from 'react' +import {View, StyleSheet} from 'react-native' +import {FeedViewModel} from '../../state/models/feed-view' +import {useStores} from '../../state' +import {ProfileHeader} from '../com/profile/ProfileHeader' +import {Feed} from '../com/feed/Feed' +import {ScreenParams} from '../routes' +import {useLoadEffect} from '../lib/navigation' + +export const Profile = ({params}: ScreenParams) => { + const store = useStores() + const [hasSetup, setHasSetup] = useState<string>('') + const [feedView, setFeedView] = useState<FeedViewModel | undefined>() + + useLoadEffect(() => { + const author = params.name + if (feedView?.params.author === author) { + return // no change needed? or trigger refresh? + } + console.log('Fetching profile feed', author) + const newFeedView = new FeedViewModel(store, {author}) + setFeedView(newFeedView) + newFeedView + .setup() + .catch(err => console.error('Failed to fetch feed', err)) + .then(() => { + setHasSetup(author) + store.nav.setTitle(author) + }) + }, [params.name, feedView?.params.author, store]) + + // TODO + // useEffect(() => { + // return navigation.addListener('focus', () => { + // if (hasSetup === feedView?.params.author) { + // console.log('Updating profile feed', hasSetup) + // feedView?.update() + // } + // }) + // }, [navigation, feedView, hasSetup]) + + return ( + <View style={styles.container}> + <ProfileHeader user={params.name} /> + <View style={styles.feed}>{feedView && <Feed feed={feedView} />}</View> + </View> + ) +} + +const styles = StyleSheet.create({ + container: { + flexDirection: 'column', + height: '100%', + }, + feed: { + flex: 1, + }, +}) diff --git a/src/view/screens/ProfileFollowers.tsx b/src/view/screens/ProfileFollowers.tsx new file mode 100644 index 000000000..c8e752685 --- /dev/null +++ b/src/view/screens/ProfileFollowers.tsx @@ -0,0 +1,24 @@ +import React, {useLayoutEffect} from 'react' +import {TouchableOpacity} from 'react-native' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {ProfileFollowers as ProfileFollowersComponent} from '../com/profile/ProfileFollowers' +import {ScreenParams} from '../routes' + +export const ProfileFollowers = ({params}: ScreenParams) => { + const {name} = params + + // TODO + // useLayoutEffect(() => { + // navigation.setOptions({ + // headerShown: true, + // headerTitle: 'Followers', + // headerLeft: () => ( + // <TouchableOpacity onPress={() => navigation.goBack()}> + // <FontAwesomeIcon icon="arrow-left" /> + // </TouchableOpacity> + // ), + // }) + // }, [navigation]) + + return <ProfileFollowersComponent name={name} /> +} diff --git a/src/view/screens/ProfileFollows.tsx b/src/view/screens/ProfileFollows.tsx new file mode 100644 index 000000000..96ce60ddd --- /dev/null +++ b/src/view/screens/ProfileFollows.tsx @@ -0,0 +1,24 @@ +import React, {useLayoutEffect} from 'react' +import {TouchableOpacity} from 'react-native' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {ProfileFollows as ProfileFollowsComponent} from '../com/profile/ProfileFollows' +import {ScreenParams} from '../routes' + +export const ProfileFollows = ({params}: ScreenParams) => { + const {name} = params + + // TODO + // useLayoutEffect(() => { + // navigation.setOptions({ + // headerShown: true, + // headerTitle: 'Following', + // headerLeft: () => ( + // <TouchableOpacity onPress={() => navigation.goBack()}> + // <FontAwesomeIcon icon="arrow-left" /> + // </TouchableOpacity> + // ), + // }) + // }, [navigation]) + + return <ProfileFollowsComponent name={name} /> +} diff --git a/src/view/screens/Search.tsx b/src/view/screens/Search.tsx new file mode 100644 index 000000000..aea54051e --- /dev/null +++ b/src/view/screens/Search.tsx @@ -0,0 +1,11 @@ +import React from 'react' +import {Text, View} from 'react-native' +import {ScreenParams} from '../routes' + +export const Search = ({params}: ScreenParams) => { + return ( + <View style={{justifyContent: 'center', alignItems: 'center'}}> + <Text style={{fontSize: 20, fontWeight: 'bold'}}>Search</Text> + </View> + ) +} diff --git a/src/view/screens/tabroots/Signup.tsx b/src/view/screens/Signup.tsx index dc2af2b1e..a34cd5727 100644 --- a/src/view/screens/tabroots/Signup.tsx +++ b/src/view/screens/Signup.tsx @@ -1,18 +1,15 @@ import React from 'react' 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' export const Signup = observer( (/*{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>} + <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.uiIsProcessing ? ( <> <Button @@ -27,8 +24,7 @@ export const Signup = observer( ) : ( <ActivityIndicator /> )*/} - </View> - </Shell> + </View> ) }, ) diff --git a/src/view/screens/stacks/Composer.tsx b/src/view/screens/stacks/Composer.tsx deleted file mode 100644 index e1b36567a..000000000 --- a/src/view/screens/stacks/Composer.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React, {useLayoutEffect, useRef} from 'react' -import {Text, TouchableOpacity} from 'react-native' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {Shell} from '../../shell' -import type {RootTabsScreenProps} from '../../routes/types' -import {Composer as ComposerComponent} from '../../com/composer/Composer' - -export const Composer = ({ - navigation, - route, -}: RootTabsScreenProps<'Composer'>) => { - const {replyTo} = route.params - const ref = useRef<{publish: () => Promise<boolean>}>() - - useLayoutEffect(() => { - navigation.setOptions({ - headerShown: true, - headerTitle: replyTo ? 'Reply' : 'New Post', - headerLeft: () => ( - <TouchableOpacity onPress={() => navigation.goBack()}> - <FontAwesomeIcon icon="x" /> - </TouchableOpacity> - ), - headerRight: () => ( - <TouchableOpacity - onPress={() => { - if (!ref.current) { - return - } - ref.current.publish().then( - posted => { - if (posted) { - navigation.goBack() - } - }, - err => console.error('Failed to create post', err), - ) - }}> - <Text>Post</Text> - </TouchableOpacity> - ), - }) - }, [navigation, replyTo, ref]) - - return ( - <Shell> - <ComposerComponent ref={ref} replyTo={replyTo} /> - </Shell> - ) -} diff --git a/src/view/screens/stacks/PostLikedBy.tsx b/src/view/screens/stacks/PostLikedBy.tsx deleted file mode 100644 index f12990141..000000000 --- a/src/view/screens/stacks/PostLikedBy.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React, {useLayoutEffect} from 'react' -import {TouchableOpacity} from 'react-native' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {makeRecordUri} from '../../lib/strings' -import {Shell} from '../../shell' -import type {RootTabsScreenProps} from '../../routes/types' -import {PostLikedBy as PostLikedByComponent} from '../../com/post-thread/PostLikedBy' - -export const PostLikedBy = ({ - navigation, - route, -}: RootTabsScreenProps<'PostLikedBy'>) => { - const {name, recordKey} = route.params - const uri = makeRecordUri(name, 'blueskyweb.xyz:Posts', recordKey) - - useLayoutEffect(() => { - navigation.setOptions({ - headerShown: true, - headerTitle: 'Liked By', - headerLeft: () => ( - <TouchableOpacity onPress={() => navigation.goBack()}> - <FontAwesomeIcon icon="arrow-left" /> - </TouchableOpacity> - ), - }) - }, [navigation]) - - const onNavigateContent = (screen: string, props: Record<string, string>) => { - // @ts-ignore it's up to the callers to supply correct params -prf - navigation.push(screen, props) - } - - return ( - <Shell> - <PostLikedByComponent uri={uri} onNavigateContent={onNavigateContent} /> - </Shell> - ) -} diff --git a/src/view/screens/stacks/PostRepostedBy.tsx b/src/view/screens/stacks/PostRepostedBy.tsx deleted file mode 100644 index 000c1a7fc..000000000 --- a/src/view/screens/stacks/PostRepostedBy.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import React, {useLayoutEffect} from 'react' -import {TouchableOpacity} from 'react-native' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {makeRecordUri} from '../../lib/strings' -import {Shell} from '../../shell' -import type {RootTabsScreenProps} from '../../routes/types' -import {PostRepostedBy as PostRepostedByComponent} from '../../com/post-thread/PostRepostedBy' - -export const PostRepostedBy = ({ - navigation, - route, -}: RootTabsScreenProps<'PostRepostedBy'>) => { - const {name, recordKey} = route.params - const uri = makeRecordUri(name, 'blueskyweb.xyz:Posts', recordKey) - - useLayoutEffect(() => { - navigation.setOptions({ - headerShown: true, - headerTitle: 'Reposted By', - headerLeft: () => ( - <TouchableOpacity onPress={() => navigation.goBack()}> - <FontAwesomeIcon icon="arrow-left" /> - </TouchableOpacity> - ), - }) - }, [navigation]) - - const onNavigateContent = (screen: string, props: Record<string, string>) => { - // @ts-ignore it's up to the callers to supply correct params -prf - navigation.push(screen, props) - } - - return ( - <Shell> - <PostRepostedByComponent - uri={uri} - onNavigateContent={onNavigateContent} - /> - </Shell> - ) -} diff --git a/src/view/screens/stacks/PostThread.tsx b/src/view/screens/stacks/PostThread.tsx deleted file mode 100644 index 485a2e49a..000000000 --- a/src/view/screens/stacks/PostThread.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React, {useLayoutEffect} from 'react' -import {TouchableOpacity} from 'react-native' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {makeRecordUri} from '../../lib/strings' -import {Shell} from '../../shell' -import type {RootTabsScreenProps} from '../../routes/types' -import {PostThread as PostThreadComponent} from '../../com/post-thread/PostThread' - -export const PostThread = ({ - navigation, - route, -}: RootTabsScreenProps<'PostThread'>) => { - const {name, recordKey} = route.params - const uri = makeRecordUri(name, 'blueskyweb.xyz:Posts', recordKey) - - useLayoutEffect(() => { - navigation.setOptions({ - headerShown: true, - headerTitle: 'Thread', - headerLeft: () => ( - <TouchableOpacity onPress={() => navigation.goBack()}> - <FontAwesomeIcon icon="arrow-left" /> - </TouchableOpacity> - ), - }) - }, [navigation]) - - const onNavigateContent = (screen: string, props: Record<string, string>) => { - // @ts-ignore it's up to the callers to supply correct params -prf - navigation.push(screen, props) - } - - return ( - <Shell> - <PostThreadComponent uri={uri} onNavigateContent={onNavigateContent} /> - </Shell> - ) -} diff --git a/src/view/screens/stacks/Profile.tsx b/src/view/screens/stacks/Profile.tsx deleted file mode 100644 index d8de12436..000000000 --- a/src/view/screens/stacks/Profile.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import React, {useState, useEffect} from 'react' -import {View, StyleSheet} from 'react-native' -import {Shell} from '../../shell' -import type {RootTabsScreenProps} from '../../routes/types' -import {FeedViewModel} from '../../../state/models/feed-view' -import {useStores} from '../../../state' -import {ProfileHeader} from '../../com/profile/ProfileHeader' -import {Feed} from '../../com/feed/Feed' - -export const Profile = ({ - navigation, - route, -}: RootTabsScreenProps<'Profile'>) => { - const store = useStores() - const [hasSetup, setHasSetup] = useState<string>('') - const [feedView, setFeedView] = useState<FeedViewModel | undefined>() - - useEffect(() => { - const author = route.params.name - if (feedView?.params.author === author) { - return // no change needed? or trigger refresh? - } - console.log('Fetching profile feed', author) - const newFeedView = new FeedViewModel(store, {author}) - setFeedView(newFeedView) - newFeedView - .setup() - .catch(err => console.error('Failed to fetch feed', err)) - .then(() => setHasSetup(author)) - }, [route.params.name, feedView?.params.author, store]) - - useEffect(() => { - return navigation.addListener('focus', () => { - if (hasSetup === feedView?.params.author) { - console.log('Updating profile feed', hasSetup) - feedView?.update() - } - }) - }, [navigation, feedView, hasSetup]) - - const onNavigateContent = (screen: string, props: Record<string, string>) => { - // @ts-ignore it's up to the callers to supply correct params -prf - navigation.push(screen, props) - } - - return ( - <Shell> - <View style={styles.container}> - <ProfileHeader - user={route.params.name} - onNavigateContent={onNavigateContent} - /> - <View style={styles.feed}> - {feedView && ( - <Feed feed={feedView} onNavigateContent={onNavigateContent} /> - )} - </View> - </View> - </Shell> - ) -} - -const styles = StyleSheet.create({ - container: { - flexDirection: 'column', - height: '100%', - }, - feed: { - flex: 1, - }, -}) diff --git a/src/view/screens/stacks/ProfileFollowers.tsx b/src/view/screens/stacks/ProfileFollowers.tsx deleted file mode 100644 index 48fbb4e13..000000000 --- a/src/view/screens/stacks/ProfileFollowers.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, {useLayoutEffect} from 'react' -import {TouchableOpacity} from 'react-native' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {Shell} from '../../shell' -import type {RootTabsScreenProps} from '../../routes/types' -import {ProfileFollowers as ProfileFollowersComponent} from '../../com/profile/ProfileFollowers' - -export const ProfileFollowers = ({ - navigation, - route, -}: RootTabsScreenProps<'ProfileFollowers'>) => { - const {name} = route.params - - useLayoutEffect(() => { - navigation.setOptions({ - headerShown: true, - headerTitle: 'Followers', - headerLeft: () => ( - <TouchableOpacity onPress={() => navigation.goBack()}> - <FontAwesomeIcon icon="arrow-left" /> - </TouchableOpacity> - ), - }) - }, [navigation]) - - const onNavigateContent = (screen: string, props: Record<string, string>) => { - // @ts-ignore it's up to the callers to supply correct params -prf - navigation.push(screen, props) - } - - return ( - <Shell> - <ProfileFollowersComponent - name={name} - onNavigateContent={onNavigateContent} - /> - </Shell> - ) -} diff --git a/src/view/screens/stacks/ProfileFollows.tsx b/src/view/screens/stacks/ProfileFollows.tsx deleted file mode 100644 index 6fce3d798..000000000 --- a/src/view/screens/stacks/ProfileFollows.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, {useLayoutEffect} from 'react' -import {TouchableOpacity} from 'react-native' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {Shell} from '../../shell' -import type {RootTabsScreenProps} from '../../routes/types' -import {ProfileFollows as ProfileFollowsComponent} from '../../com/profile/ProfileFollows' - -export const ProfileFollows = ({ - navigation, - route, -}: RootTabsScreenProps<'ProfileFollows'>) => { - const {name} = route.params - - useLayoutEffect(() => { - navigation.setOptions({ - headerShown: true, - headerTitle: 'Following', - headerLeft: () => ( - <TouchableOpacity onPress={() => navigation.goBack()}> - <FontAwesomeIcon icon="arrow-left" /> - </TouchableOpacity> - ), - }) - }, [navigation]) - - const onNavigateContent = (screen: string, props: Record<string, string>) => { - // @ts-ignore it's up to the callers to supply correct params -prf - navigation.push(screen, props) - } - - return ( - <Shell> - <ProfileFollowsComponent - name={name} - onNavigateContent={onNavigateContent} - /> - </Shell> - ) -} diff --git a/src/view/screens/tabroots/Home.tsx b/src/view/screens/tabroots/Home.tsx deleted file mode 100644 index a9c952473..000000000 --- a/src/view/screens/tabroots/Home.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import React, {useState, useEffect, useLayoutEffect} from 'react' -import {Image, StyleSheet, TouchableOpacity, View} from 'react-native' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {Shell} from '../../shell' -import {Feed} from '../../com/feed/Feed' -import type {RootTabsScreenProps} from '../../routes/types' -import {useStores} from '../../../state' -import {AVIS} from '../../lib/assets' - -export function Home({navigation}: RootTabsScreenProps<'HomeTab'>) { - const [hasSetup, setHasSetup] = useState<boolean>(false) - const store = useStores() - useEffect(() => { - console.log('Fetching home feed') - store.homeFeed.setup().then(() => setHasSetup(true)) - }, [store.homeFeed]) - - const onNavigateContent = (screen: string, props: Record<string, string>) => { - // @ts-ignore it's up to the callers to supply correct params -prf - navigation.navigate(screen, props) - } - - useEffect(() => { - return navigation.addListener('focus', () => { - if (hasSetup) { - console.log('Updating home feed') - store.homeFeed.update() - } - }) - }, [navigation, store.homeFeed, hasSetup]) - - useLayoutEffect(() => { - navigation.setOptions({ - headerShown: true, - headerTitle: 'V I B E', - headerLeft: () => ( - <TouchableOpacity - onPress={() => navigation.push('Profile', {name: 'alice.com'})}> - <Image source={AVIS['alice.com']} style={styles.avi} /> - </TouchableOpacity> - ), - headerRight: () => ( - <TouchableOpacity - onPress={() => { - navigation.push('Composer', {}) - }}> - <FontAwesomeIcon icon="plus" style={{color: '#006bf7'}} /> - </TouchableOpacity> - ), - }) - }, [navigation]) - - return ( - <Shell> - <View> - <Feed feed={store.homeFeed} onNavigateContent={onNavigateContent} /> - </View> - </Shell> - ) -} - -const styles = StyleSheet.create({ - avi: { - width: 20, - height: 20, - borderRadius: 10, - resizeMode: 'cover', - }, -}) diff --git a/src/view/screens/tabroots/Menu.tsx b/src/view/screens/tabroots/Menu.tsx deleted file mode 100644 index dca5ad33b..000000000 --- a/src/view/screens/tabroots/Menu.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react' -import {Shell} from '../../shell' -import {ScrollView, Text, View} from 'react-native' -import type {RootTabsScreenProps} from '../../routes/types' - -export const Menu = (_props: RootTabsScreenProps<'MenuTab'>) => { - return ( - <Shell> - <ScrollView contentInsetAdjustmentBehavior="automatic"> - <View style={{justifyContent: 'center', alignItems: 'center'}}> - <Text style={{fontSize: 20, fontWeight: 'bold'}}>Menu</Text> - </View> - </ScrollView> - </Shell> - ) -} diff --git a/src/view/screens/tabroots/NotFound.tsx b/src/view/screens/tabroots/NotFound.tsx deleted file mode 100644 index a35808cbc..000000000 --- a/src/view/screens/tabroots/NotFound.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react' -import {Shell} from '../../shell' -import {Text, Button, View} from 'react-native' -import type {RootTabsScreenProps} from '../../routes/types' - -export const NotFound = ({navigation}: RootTabsScreenProps<'NotFound'>) => { - return ( - <Shell> - <View style={{justifyContent: 'center', alignItems: 'center'}}> - <Text style={{fontSize: 20, fontWeight: 'bold'}}>Page not found</Text> - <Button title="Home" onPress={() => navigation.navigate('HomeTab')} /> - </View> - </Shell> - ) -} diff --git a/src/view/screens/tabroots/Notifications.tsx b/src/view/screens/tabroots/Notifications.tsx deleted file mode 100644 index ea7576799..000000000 --- a/src/view/screens/tabroots/Notifications.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import React, {useState, useEffect, useLayoutEffect} from 'react' -import {Image, StyleSheet, TouchableOpacity, View} from 'react-native' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {Shell} from '../../shell' -import {Feed} from '../../com/notifications/Feed' -import type {RootTabsScreenProps} from '../../routes/types' -import {useStores} from '../../../state' -import {AVIS} from '../../lib/assets' - -export const Notifications = ({ - navigation, -}: RootTabsScreenProps<'NotificationsTab'>) => { - const [hasSetup, setHasSetup] = useState<boolean>(false) - const store = useStores() - useEffect(() => { - console.log('Fetching home feed') - store.notesFeed.setup().then(() => setHasSetup(true)) - }, [store.notesFeed]) - - const onNavigateContent = (screen: string, props: Record<string, string>) => { - // @ts-ignore it's up to the callers to supply correct params -prf - navigation.navigate(screen, props) - } - - useEffect(() => { - return navigation.addListener('focus', () => { - if (hasSetup) { - console.log('Updating home feed') - store.notesFeed.update() - } - }) - }, [navigation, store.notesFeed, hasSetup]) - - useLayoutEffect(() => { - navigation.setOptions({ - headerShown: true, - headerTitle: 'Notifications', - headerLeft: () => ( - <TouchableOpacity - onPress={() => navigation.push('Profile', {name: 'alice.com'})}> - <Image source={AVIS['alice.com']} style={styles.avi} /> - </TouchableOpacity> - ), - headerRight: () => ( - <TouchableOpacity - onPress={() => { - navigation.push('Composer', {}) - }}> - <FontAwesomeIcon icon="plus" style={{color: '#006bf7'}} /> - </TouchableOpacity> - ), - }) - }, [navigation]) - - return ( - <Shell> - <View> - <Feed view={store.notesFeed} onNavigateContent={onNavigateContent} /> - </View> - </Shell> - ) -} - -const styles = StyleSheet.create({ - avi: { - width: 20, - height: 20, - borderRadius: 10, - resizeMode: 'cover', - }, -}) diff --git a/src/view/screens/tabroots/Search.tsx b/src/view/screens/tabroots/Search.tsx deleted file mode 100644 index 044ca749c..000000000 --- a/src/view/screens/tabroots/Search.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react' -import {Shell} from '../../shell' -import {Text, View} from 'react-native' -import type {RootTabsScreenProps} from '../../routes/types' - -export const Search = (_props: RootTabsScreenProps<'SearchTab'>) => { - return ( - <Shell> - <View style={{justifyContent: 'center', alignItems: 'center'}}> - <Text style={{fontSize: 20, fontWeight: 'bold'}}>Search</Text> - </View> - </Shell> - ) -} |