diff --git a/src/state/models/feeds/actor.ts b/src/state/models/feeds/actor.ts
index e660d4eb..08b7c2a7 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 d06a196f..86199108 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 00000000..57a1428e
--- /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 (
+
+
+
+
+
+
+
+ {item.displayName ?? 'Feed name'}
+
+
+ {item.description ??
+ 'THIS IS A FEED DESCRIPTION, IT WILL TELL YOU WHAT THE FEED IS ABOUT. THIS IS A COOL FEED ABOUT COOL PEOPLE.'}
+
+
+
+
+ {/* TODO: this feed is like by *3* people UserAvatars and others */}
+
+ )
+}
+
+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 5fb21255..b88caf1f 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
export const ProfileScreen = withAuthRequired(
@@ -152,15 +154,14 @@ export const ProfileScreen = withAuthRequired(
)
} else if (item instanceof PostsFeedSliceModel) {
return
+ } 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
}
return
},
- [
- onPressTryAgain,
- uiState.profile.did,
- uiState.feed.isBlocking,
- uiState.feed.isBlockedBy,
- ],
+ [onPressTryAgain, uiState],
)
return (