about summary refs log tree commit diff
path: root/src/view
diff options
context:
space:
mode:
Diffstat (limited to 'src/view')
-rw-r--r--src/view/com/auth/onboarding/RecommendedFeeds.tsx70
-rw-r--r--src/view/com/auth/onboarding/RecommendedFeedsItem.tsx11
-rw-r--r--src/view/shell/Drawer.tsx9
-rw-r--r--src/view/shell/bottom-bar/BottomBarWeb.tsx28
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})}