Files
bsky-social-app/src/state/models/suggested-posts-view.ts
T
Ansh bd9386d81c New onboarding (#241)
* delete old onboarding files and code

* add custom FollowButton component to Post, FeedItem, & ProfileCard

* move building suggested feed into helper lib

* show suggested posts/feed if follower list is empty

* Update tsconfig.json

* add pagination to getting new onboarding

* remove unnecessary console log

* fix naming, add better null check for combinedCursor

* In locally-combined feeds, correctly produce an undefined cursor when out of data

* Minor refactors of the suggested posts lib functions

* Show 'follow button' style of post meta in certain conditions only

* Only show follow btn in posts on the main feed and the discovery feed

* Add a welcome notice to the home feed

* Tune the timing of when the welcome banner shows or hides

* Make the follow button an observer (closes #244)

* Update postmeta to keep the follow btn after press until next render

* A couple of fixes that ensure consistent welcome screen

* Fix lint

* Rework the welcome banner

* Fix cache invalidation of follows model on user switch

* Show welcome banner while loading

* Update the home onboarding feed to get top posts from hardcode recommends

* Drop unused helper function

* Update happy path tests

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
2023-03-02 12:21:33 -06:00

87 lines
1.9 KiB
TypeScript

import {makeAutoObservable, runInAction} from 'mobx'
import {RootStoreModel} from './root-store'
import {FeedItemModel} from './feed-view'
import {cleanError} from 'lib/strings/errors'
import {TEAM_HANDLES} from 'lib/constants'
import {
getMultipleAuthorsPosts,
mergePosts,
} from 'lib/api/build-suggested-posts'
export class SuggestedPostsView {
// state
isLoading = false
hasLoaded = false
error = ''
// data
posts: FeedItemModel[] = []
constructor(public rootStore: RootStoreModel) {
makeAutoObservable(
this,
{
rootStore: false,
},
{autoBind: true},
)
}
get hasContent() {
return this.posts.length > 0
}
get hasError() {
return this.error !== ''
}
get isEmpty() {
return this.hasLoaded && !this.hasContent
}
// public api
// =
async setup() {
this._xLoading()
try {
const responses = await getMultipleAuthorsPosts(
this.rootStore,
TEAM_HANDLES(String(this.rootStore.agent.service)),
)
runInAction(() => {
const finalPosts = mergePosts(responses, {repostsOnly: true})
// hydrate into models
this.posts = finalPosts.map((post, i) => {
// strip the reasons to hide that these are reposts
delete post.reason
return new FeedItemModel(this.rootStore, `post-${i}`, post)
})
})
this._xIdle()
} catch (e: any) {
this.rootStore.log.error('SuggestedPostsView: Failed to load posts', {
e,
})
this._xIdle() // dont bubble to the user
}
}
// state transitions
// =
private _xLoading() {
this.isLoading = true
this.error = ''
}
private _xIdle(err?: any) {
this.isLoading = false
this.hasLoaded = true
this.error = cleanError(err)
if (err) {
this.rootStore.log.error('Failed to fetch suggested posts', err)
}
}
}