about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAnsh Nanda <anshnanda10@gmail.com>2023-05-12 19:32:39 -0700
committerAnsh Nanda <anshnanda10@gmail.com>2023-05-12 19:32:39 -0700
commit760b5309e09251023682d8a93ed331ff921817ea (patch)
tree0872559ed131687a7e31388240ef7f4da5b9224c /src
parentfa4af20764b0596420c1e2a8dd981dc34020e205 (diff)
downloadvoidsky-760b5309e09251023682d8a93ed331ff921817ea.tar.zst
show algos by user on profile
Diffstat (limited to 'src')
-rw-r--r--src/state/models/feeds/actor.ts16
-rw-r--r--src/state/models/ui/profile.ts30
-rw-r--r--src/view/com/algos/AlgoItem.tsx57
-rw-r--r--src/view/screens/Profile.tsx13
4 files changed, 99 insertions, 17 deletions
diff --git a/src/state/models/feeds/actor.ts b/src/state/models/feeds/actor.ts
index e660d4eb8..08b7c2a74 100644
--- a/src/state/models/feeds/actor.ts
+++ b/src/state/models/feeds/actor.ts
@@ -1,9 +1,7 @@
 import {makeAutoObservable} from 'mobx'
 import {
-  AppBskyFeedGetBookmarkedFeeds as GetBookmarkedFeeds,
-  // AppBskyFeedBookmarkFeed as bookmarkedFeed,
-  // AppBskyFeedUnbookmarkFeed as unbookmarkFeed,
   AppBskyFeedDefs as FeedDefs,
+  AppBskyFeedGetActorFeeds as GetActorFeeds,
 } from '@atproto/api'
 import {RootStoreModel} from '../root-store'
 import {bundleAsync} from 'lib/async/bundle'
@@ -23,7 +21,10 @@ export class ActorFeedsModel {
   // data
   feeds: FeedDefs.GeneratorView[] = []
 
-  constructor(public rootStore: RootStoreModel) {
+  constructor(
+    public rootStore: RootStoreModel,
+    public params: GetActorFeeds.QueryParams,
+  ) {
     makeAutoObservable(
       this,
       {
@@ -69,10 +70,11 @@ export class ActorFeedsModel {
     this._xLoading(replace)
     try {
       const res = await this.rootStore.agent.app.bsky.feed.getActorFeeds({
-        actor: 'did:plc:dpny6d4qwwxu5b6dp3qob5ok', // TODO: take this as input param
+        actor: this.params.actor,
         limit: PAGE_SIZE,
         cursor: replace ? undefined : this.loadMoreCursor,
       })
+      console.log('res', res.data.feeds)
       if (replace) {
         this._replaceAll(res)
       } else {
@@ -106,12 +108,12 @@ export class ActorFeedsModel {
   // helper functions
   // =
 
-  _replaceAll(res: GetBookmarkedFeeds.Response) {
+  _replaceAll(res: GetActorFeeds.Response) {
     this.feeds = []
     this._appendAll(res)
   }
 
-  _appendAll(res: GetBookmarkedFeeds.Response) {
+  _appendAll(res: GetActorFeeds.Response) {
     this.loadMoreCursor = res.data.cursor
     this.hasMore = !!this.loadMoreCursor
     this.feeds = this.feeds.concat(res.data.feeds)
diff --git a/src/state/models/ui/profile.ts b/src/state/models/ui/profile.ts
index d06a196f3..86199108e 100644
--- a/src/state/models/ui/profile.ts
+++ b/src/state/models/ui/profile.ts
@@ -2,13 +2,20 @@ import {makeAutoObservable} from 'mobx'
 import {RootStoreModel} from '../root-store'
 import {ProfileModel} from '../content/profile'
 import {PostsFeedModel} from '../feeds/posts'
+import {ActorFeedsModel} from '../feeds/actor'
+import {AppBskyFeedDefs} from '@atproto/api'
 
 export enum Sections {
   Posts = 'Posts',
   PostsWithReplies = 'Posts & replies',
+  CustomAlgorithms = 'Algos',
 }
 
-const USER_SELECTOR_ITEMS = [Sections.Posts, Sections.PostsWithReplies]
+const USER_SELECTOR_ITEMS = [
+  Sections.Posts,
+  Sections.PostsWithReplies,
+  Sections.CustomAlgorithms,
+]
 
 export interface ProfileUiParams {
   user: string
@@ -22,6 +29,7 @@ export class ProfileUiModel {
   // data
   profile: ProfileModel
   feed: PostsFeedModel
+  algos: ActorFeedsModel
 
   // ui state
   selectedViewIndex = 0
@@ -43,15 +51,19 @@ export class ProfileUiModel {
       actor: params.user,
       limit: 10,
     })
+    this.algos = new ActorFeedsModel(rootStore, {actor: params.user})
   }
 
-  get currentView(): PostsFeedModel {
+  get currentView(): PostsFeedModel | ActorFeedsModel {
     if (
       this.selectedView === Sections.Posts ||
       this.selectedView === Sections.PostsWithReplies
     ) {
       return this.feed
     }
+    if (this.selectedView === Sections.CustomAlgorithms) {
+      return this.algos
+    }
     throw new Error(`Invalid selector value: ${this.selectedViewIndex}`)
   }
 
@@ -71,12 +83,17 @@ export class ProfileUiModel {
   get selectedView() {
     return this.selectorItems[this.selectedViewIndex]
   }
+  isGeneratorView(v: any) {
+    return AppBskyFeedDefs.isGeneratorView(v)
+  }
 
   get uiItems() {
     let arr: any[] = []
+    // if loading, return loading item to show loading spinner
     if (this.isInitialLoading) {
       arr = arr.concat([ProfileUiModel.LOADING_ITEM])
     } else if (this.currentView.hasError) {
+      // if error, return error item to show error message
       arr = arr.concat([
         {
           _reactKey: '__error__',
@@ -84,12 +101,16 @@ export class ProfileUiModel {
         },
       ])
     } else {
+      // not loading, no error, show content
       if (
         this.selectedView === Sections.Posts ||
-        this.selectedView === Sections.PostsWithReplies
+        this.selectedView === Sections.PostsWithReplies ||
+        this.selectedView === Sections.CustomAlgorithms
       ) {
         if (this.feed.hasContent) {
-          if (this.selectedView === Sections.Posts) {
+          if (this.selectedView === Sections.CustomAlgorithms) {
+            arr = this.algos.feeds
+          } else if (this.selectedView === Sections.Posts) {
             arr = this.feed.nonReplyFeed
           } else {
             arr = this.feed.slices.slice()
@@ -101,6 +122,7 @@ export class ProfileUiModel {
           arr = arr.concat([ProfileUiModel.EMPTY_ITEM])
         }
       } else {
+        // fallback, add empty item, to show empty message
         arr = arr.concat([ProfileUiModel.EMPTY_ITEM])
       }
     }
diff --git a/src/view/com/algos/AlgoItem.tsx b/src/view/com/algos/AlgoItem.tsx
new file mode 100644
index 000000000..57a1428e6
--- /dev/null
+++ b/src/view/com/algos/AlgoItem.tsx
@@ -0,0 +1,57 @@
+import React from 'react'
+import {StyleSheet, View} from 'react-native'
+import {Text} from '../util/text/Text'
+import {AppBskyFeedDefs} from '@atproto/api'
+import {usePalette} from 'lib/hooks/usePalette'
+import {s} from 'lib/styles'
+import {UserAvatar} from '../util/UserAvatar'
+
+const AlgoItem = ({item}: {item: AppBskyFeedDefs.GeneratorView}) => {
+  const pal = usePalette('default')
+  return (
+    <View style={[styles.container]} key={item.uri}>
+      <View style={[styles.headerContainer]}>
+        <View style={[s.mr20]}>
+          <UserAvatar size={56} avatar={item.avatar} />
+        </View>
+        <View style={[styles.headerTextContainer]}>
+          <Text style={[pal.text, s.bold]}>
+            {item.displayName ?? 'Feed name'}
+          </Text>
+          <Text style={[pal.textLight, styles.description]}>
+            {item.description ??
+              'THIS IS A FEED DESCRIPTION, IT WILL TELL YOU WHAT THE FEED IS ABOUT. THIS IS A COOL FEED ABOUT COOL PEOPLE.'}
+          </Text>
+        </View>
+      </View>
+
+      {/* TODO: this feed is like by *3* people UserAvatars and others */}
+    </View>
+  )
+}
+
+export default AlgoItem
+
+const styles = StyleSheet.create({
+  container: {
+    paddingHorizontal: 18,
+    paddingVertical: 20,
+    flexDirection: 'column',
+    columnGap: 36,
+    flex: 1,
+    borderTopWidth: 1,
+    borderTopColor: '#E5E5E5',
+  },
+  headerContainer: {
+    flexDirection: 'row',
+  },
+  headerTextContainer: {
+    flexDirection: 'column',
+    columnGap: 4,
+    flex: 1,
+  },
+  description: {
+    flex: 1,
+    flexWrap: 'wrap',
+  },
+})
diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx
index 5fb212554..b88caf1f8 100644
--- a/src/view/screens/Profile.tsx
+++ b/src/view/screens/Profile.tsx
@@ -21,6 +21,8 @@ import {FAB} from '../com/util/fab/FAB'
 import {s, colors} from 'lib/styles'
 import {useAnalytics} from 'lib/analytics'
 import {ComposeIcon2} from 'lib/icons'
+import {AppBskyFeedDefs} from '@atproto/api'
+import AlgoItem from 'view/com/algos/AlgoItem'
 
 type Props = NativeStackScreenProps<CommonNavigatorParams, 'Profile'>
 export const ProfileScreen = withAuthRequired(
@@ -152,15 +154,14 @@ export const ProfileScreen = withAuthRequired(
           )
         } else if (item instanceof PostsFeedSliceModel) {
           return <FeedSlice slice={item} ignoreMuteFor={uiState.profile.did} />
+        } else if (item.creator) {
+          // TODO: this is a hack to see if it is a custom feed. fix it to something more robust
+          const typedItem = item as AppBskyFeedDefs.GeneratorView
+          return <AlgoItem item={typedItem} />
         }
         return <View />
       },
-      [
-        onPressTryAgain,
-        uiState.profile.did,
-        uiState.feed.isBlocking,
-        uiState.feed.isBlockedBy,
-      ],
+      [onPressTryAgain, uiState],
     )
 
     return (