diff options
author | Eric Bailey <git@esb.lol> | 2023-08-03 12:00:38 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-03 10:00:38 -0700 |
commit | 1211c353d0ef67f7a2d97e819dac488b14b73a08 (patch) | |
tree | 2b4c677a0cf1802e2eb5b6030bbb832b2e3ae3bb /src | |
parent | a63f97aef2ea70ff9f1b81d40073f36ae8e88278 (diff) | |
download | voidsky-1211c353d0ef67f7a2d97e819dac488b14b73a08.tar.zst |
resolve did before loading feed (#1092)
* resolve did before loading feed * add loader * wrap with authRequired, handle errors
Diffstat (limited to 'src')
-rw-r--r-- | src/view/screens/CustomFeed.tsx | 108 |
1 files changed, 98 insertions, 10 deletions
diff --git a/src/view/screens/CustomFeed.tsx b/src/view/screens/CustomFeed.tsx index d5ecff042..265f8a94c 100644 --- a/src/view/screens/CustomFeed.tsx +++ b/src/view/screens/CustomFeed.tsx @@ -1,13 +1,14 @@ import React, {useMemo, useRef} from 'react' import {NativeStackScreenProps} from '@react-navigation/native-stack' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {useNavigation} from '@react-navigation/native' import {usePalette} from 'lib/hooks/usePalette' import {HeartIcon, HeartIconSolid} from 'lib/icons' import {CommonNavigatorParams} from 'lib/routes/types' import {makeRecordUri} from 'lib/strings/url-helpers' import {colors, s} from 'lib/styles' import {observer} from 'mobx-react-lite' -import {FlatList, StyleSheet, View} from 'react-native' +import {FlatList, StyleSheet, View, ActivityIndicator} from 'react-native' import {useStores} from 'state/index' import {PostsFeedModel} from 'state/models/feeds/posts' import {useCustomFeed} from 'lib/hooks/useCustomFeed' @@ -34,17 +35,98 @@ import {EmptyState} from 'view/com/util/EmptyState' import {useAnalytics} from 'lib/analytics/analytics' import {NativeDropdown, DropdownItem} from 'view/com/util/forms/NativeDropdown' import {makeProfileLink} from 'lib/routes/links' +import {resolveName} from 'lib/api' +import {CenteredView} from 'view/com/util/Views' +import {NavigationProp} from 'lib/routes/types' type Props = NativeStackScreenProps<CommonNavigatorParams, 'CustomFeed'> + export const CustomFeedScreen = withAuthRequired( - observer(({route}: Props) => { + observer((props: Props) => { + const pal = usePalette('default') + const store = useStores() + const navigation = useNavigation<NavigationProp>() + + const {name: handleOrDid} = props.route.params + + const [feedOwnerDid, setFeedOwnerDid] = React.useState<string | undefined>() + const [error, setError] = React.useState<string | undefined>() + + const onPressBack = React.useCallback(() => { + if (navigation.canGoBack()) { + navigation.goBack() + } else { + navigation.navigate('Home') + } + }, [navigation]) + + React.useEffect(() => { + /* + * We must resolve the DID of the feed owner before we can fetch the feed. + */ + async function fetchDid() { + try { + const did = await resolveName(store, handleOrDid) + setFeedOwnerDid(did) + } catch (e) { + setError( + `We're sorry, but we were unable to resolve this feed. If this persists, please contact the feed creator, @${handleOrDid}.`, + ) + } + } + + fetchDid() + }, [store, handleOrDid, setFeedOwnerDid]) + + if (error) { + return ( + <CenteredView> + <View style={[pal.view, pal.border, styles.notFoundContainer]}> + <Text type="title-lg" style={[pal.text, s.mb10]}> + Could not load feed + </Text> + <Text type="md" style={[pal.text, s.mb20]}> + {error} + </Text> + + <View style={{flexDirection: 'row'}}> + <Button + type="default" + accessibilityLabel="Go Back" + accessibilityHint="Return to previous page" + onPress={onPressBack} + style={{flexShrink: 1}}> + <Text type="button" style={pal.text}> + Go Back + </Text> + </Button> + </View> + </View> + </CenteredView> + ) + } + + return feedOwnerDid ? ( + <CustomFeedScreenInner {...props} feedOwnerDid={feedOwnerDid} /> + ) : ( + <CenteredView> + <View style={s.p20}> + <ActivityIndicator size="large" /> + </View> + </CenteredView> + ) + }), +) + +export const CustomFeedScreenInner = observer( + ({route, feedOwnerDid}: Props & {feedOwnerDid: string}) => { const store = useStores() const pal = usePalette('default') const {track} = useAnalytics() - const {rkey, name} = route.params + const {rkey, name: handleOrDid} = route.params const uri = useMemo( - () => makeRecordUri(name, 'app.bsky.feed.generator', rkey), - [rkey, name], + () => makeRecordUri(feedOwnerDid, 'app.bsky.feed.generator', rkey), + [rkey, feedOwnerDid], ) const scrollElRef = useRef<FlatList>(null) const currentFeed = useCustomFeed(uri) @@ -101,10 +183,10 @@ export const CustomFeedScreen = withAuthRequired( }, [store, currentFeed]) const onPressShare = React.useCallback(() => { - const url = toShareUrl(`/profile/${name}/feed/${rkey}`) + const url = toShareUrl(`/profile/${handleOrDid}/feed/${rkey}`) shareUrl(url) track('CustomFeed:Share') - }, [name, rkey, track]) + }, [handleOrDid, rkey, track]) const onScrollToTop = React.useCallback(() => { scrollElRef.current?.scrollToOffset({offset: 0, animated: true}) @@ -310,7 +392,7 @@ export const CustomFeedScreen = withAuthRequired( <TextLink type="md-medium" style={pal.textLight} - href={`/profile/${name}/feed/${rkey}/liked-by`} + href={`/profile/${handleOrDid}/feed/${rkey}/liked-by`} text={`Liked by ${currentFeed.data.likeCount} ${pluralize( currentFeed?.data.likeCount || 0, 'user', @@ -336,7 +418,7 @@ export const CustomFeedScreen = withAuthRequired( onToggleSaved, onToggleLiked, onPressShare, - name, + handleOrDid, rkey, isPinned, onTogglePinned, @@ -375,7 +457,7 @@ export const CustomFeedScreen = withAuthRequired( /> </View> ) - }), + }, ) const styles = StyleSheet.create({ @@ -430,4 +512,10 @@ const styles = StyleSheet.create({ position: 'relative', top: 2, }, + notFoundContainer: { + margin: 10, + paddingHorizontal: 18, + paddingVertical: 14, + borderRadius: 6, + }, }) |