diff options
Diffstat (limited to 'src/view')
-rw-r--r-- | src/view/com/auth/onboarding/RecommendedFeeds.tsx | 70 | ||||
-rw-r--r-- | src/view/com/auth/onboarding/RecommendedFeedsItem.tsx | 11 | ||||
-rw-r--r-- | src/view/shell/Drawer.tsx | 9 | ||||
-rw-r--r-- | src/view/shell/bottom-bar/BottomBarWeb.tsx | 28 |
4 files changed, 86 insertions, 32 deletions
diff --git a/src/view/com/auth/onboarding/RecommendedFeeds.tsx b/src/view/com/auth/onboarding/RecommendedFeeds.tsx index 99cdcafd0..8e29a5895 100644 --- a/src/view/com/auth/onboarding/RecommendedFeeds.tsx +++ b/src/view/com/auth/onboarding/RecommendedFeeds.tsx @@ -1,5 +1,5 @@ import React from 'react' -import {FlatList, StyleSheet, View} from 'react-native' +import {ActivityIndicator, FlatList, StyleSheet, View} from 'react-native' import {observer} from 'mobx-react-lite' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {TabletOrDesktop, Mobile} from 'view/com/util/layouts/Breakpoints' @@ -10,7 +10,10 @@ import {Button} from 'view/com/util/forms/Button' import {RecommendedFeedsItem} from './RecommendedFeedsItem' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {usePalette} from 'lib/hooks/usePalette' -import {RECOMMENDED_FEEDS} from 'lib/constants' +import {useQuery} from '@tanstack/react-query' +import {useStores} from 'state/index' +import {CustomFeedModel} from 'state/models/feeds/custom-feed' +import {ErrorMessage} from 'view/com/util/error/ErrorMessage' type Props = { next: () => void @@ -18,8 +21,31 @@ type Props = { export const RecommendedFeeds = observer(function RecommendedFeedsImpl({ next, }: Props) { + const store = useStores() const pal = usePalette('default') const {isTabletOrMobile} = useWebMediaQueries() + const {isLoading, data: recommendedFeeds} = useQuery({ + staleTime: Infinity, // fixed list rn, never refetch + queryKey: ['onboarding', 'recommended_feeds'], + async queryFn() { + try { + const { + data: {feeds}, + success, + } = await store.agent.app.bsky.feed.getSuggestedFeeds() + + if (!success) return + + return (feeds.length ? feeds : []).map(feed => { + return new CustomFeedModel(store, feed) + }) + } catch (e) { + return + } + }, + }) + + const hasFeeds = recommendedFeeds && recommendedFeeds.length const title = ( <> @@ -86,12 +112,20 @@ export const RecommendedFeeds = observer(function RecommendedFeedsImpl({ horizontal titleStyle={isTabletOrMobile ? undefined : {minWidth: 470}} contentStyle={{paddingHorizontal: 0}}> - <FlatList - data={RECOMMENDED_FEEDS} - renderItem={({item}) => <RecommendedFeedsItem {...item} />} - keyExtractor={item => item.did + item.rkey} - style={{flex: 1}} - /> + {hasFeeds ? ( + <FlatList + data={recommendedFeeds} + renderItem={({item}) => <RecommendedFeedsItem item={item} />} + keyExtractor={item => item.uri} + style={{flex: 1}} + /> + ) : isLoading ? ( + <View> + <ActivityIndicator size="large" /> + </View> + ) : ( + <ErrorMessage message="Failed to load recommended feeds" /> + )} </TitleColumnLayout> </TabletOrDesktop> <Mobile> @@ -106,12 +140,20 @@ export const RecommendedFeeds = observer(function RecommendedFeedsImpl({ pinned feeds. </Text> - <FlatList - data={RECOMMENDED_FEEDS} - renderItem={({item}) => <RecommendedFeedsItem {...item} />} - keyExtractor={item => item.did + item.rkey} - style={{flex: 1}} - /> + {hasFeeds ? ( + <FlatList + data={recommendedFeeds} + renderItem={({item}) => <RecommendedFeedsItem item={item} />} + keyExtractor={item => item.uri} + style={{flex: 1}} + /> + ) : isLoading ? ( + <View> + <ActivityIndicator size="large" /> + </View> + ) : ( + <ErrorMessage message="Failed to load recommended feeds" /> + )} <Button onPress={next} diff --git a/src/view/com/auth/onboarding/RecommendedFeedsItem.tsx b/src/view/com/auth/onboarding/RecommendedFeedsItem.tsx index e5d12273a..d130dc138 100644 --- a/src/view/com/auth/onboarding/RecommendedFeedsItem.tsx +++ b/src/view/com/auth/onboarding/RecommendedFeedsItem.tsx @@ -8,22 +8,17 @@ import {UserAvatar} from 'view/com/util/UserAvatar' import * as Toast from 'view/com/util/Toast' import {HeartIcon} from 'lib/icons' import {usePalette} from 'lib/hooks/usePalette' -import {useCustomFeed} from 'lib/hooks/useCustomFeed' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {makeRecordUri} from 'lib/strings/url-helpers' import {sanitizeHandle} from 'lib/strings/handles' +import {CustomFeedModel} from 'state/models/feeds/custom-feed' export const RecommendedFeedsItem = observer(function RecommendedFeedsItemImpl({ - did, - rkey, + item, }: { - did: string - rkey: string + item: CustomFeedModel }) { const {isMobile} = useWebMediaQueries() const pal = usePalette('default') - const uri = makeRecordUri(did, 'app.bsky.feed.generator', rkey) - const item = useCustomFeed(uri) if (!item) return null const onToggle = async () => { if (item.isSaved) { diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx index 3379d0501..67092938e 100644 --- a/src/view/shell/Drawer.tsx +++ b/src/view/shell/Drawer.tsx @@ -64,8 +64,13 @@ export const DrawerContent = observer(function DrawerContentImpl() { const state = navigation.getState() store.shell.closeDrawer() if (isWeb) { - // @ts-ignore must be Home, Search, Notifications, or MyProfile - navigation.navigate(tab) + // hack because we have flat navigator for web and MyProfile does not exist on the web navigator -ansh + if (tab === 'MyProfile') { + navigation.navigate('Profile', {name: store.me.handle}) + } else { + // @ts-ignore must be Home, Search, Notifications, or MyProfile + navigation.navigate(tab) + } } else { const tabState = getTabState(state, tab) if (tabState === TabState.InsideAtRoot) { diff --git a/src/view/shell/bottom-bar/BottomBarWeb.tsx b/src/view/shell/bottom-bar/BottomBarWeb.tsx index ee575c217..af70d3364 100644 --- a/src/view/shell/bottom-bar/BottomBarWeb.tsx +++ b/src/view/shell/bottom-bar/BottomBarWeb.tsx @@ -18,10 +18,12 @@ import { SatelliteDishIcon, SatelliteDishIconSolid, UserIcon, + UserIconSolid, } from 'lib/icons' import {Link} from 'view/com/util/Link' import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode' import {makeProfileLink} from 'lib/routes/links' +import {CommonNavigatorParams} from 'lib/routes/types' export const BottomBarWeb = observer(function BottomBarWebImpl() { const store = useStores() @@ -89,13 +91,16 @@ export const BottomBarWeb = observer(function BottomBarWebImpl() { }} </NavItem> <NavItem routeName="Profile" href={makeProfileLink(store.me)}> - {() => ( - <UserIcon - size={28} - strokeWidth={1.5} - style={[styles.ctrlIcon, pal.text, styles.profileIcon]} - /> - )} + {({isActive}) => { + const Icon = isActive ? UserIconSolid : UserIcon + return ( + <Icon + size={28} + strokeWidth={1.5} + style={[styles.ctrlIcon, pal.text, styles.profileIcon]} + /> + ) + }} </NavItem> </Animated.View> ) @@ -107,7 +112,14 @@ const NavItem: React.FC<{ routeName: string }> = ({children, href, routeName}) => { const currentRoute = useNavigationState(getCurrentRoute) - const isActive = isTab(currentRoute.name, routeName) + const store = useStores() + const isActive = + currentRoute.name === 'Profile' + ? isTab(currentRoute.name, routeName) && + (currentRoute.params as CommonNavigatorParams['Profile']).name === + store.me.handle + : isTab(currentRoute.name, routeName) + return ( <Link href={href} style={styles.ctrl}> {children({isActive})} |