Onboarding tweaks (#272)

* Small fix to side menu rendering

* Change onboarding to use an explicit 'is onboarding' mode to more clearly control the flow

* Add a progress bar to the welcome banner

* Dont show the 'unfollow button' on posts in weird times (close #271)

* Improve the empty state of the feed

* Only suggest recent posts
This commit is contained in:
Paul Frazee 2023-03-06 15:34:22 -06:00 committed by GitHub
parent 74c30c60b8
commit 36791e68b3
13 changed files with 259 additions and 123 deletions

View file

@ -212,7 +212,7 @@ export class FeedModel {
constructor(
public rootStore: RootStoreModel,
public feedType: 'home' | 'author',
public feedType: 'home' | 'author' | 'suggested',
params: GetTimeline.QueryParams | GetAuthorFeed.QueryParams,
) {
makeAutoObservable(
@ -256,7 +256,7 @@ export class FeedModel {
item.reply?.root.author.did === item.post.author.did)
)
})
} else {
} else if (this.feedType === 'home') {
return this.feed.filter(item => {
const isRepost = Boolean(item?.reasonRepost)
return (
@ -267,6 +267,8 @@ export class FeedModel {
item.post.upvoteCount >= 2
)
})
} else {
return this.feed
}
}
@ -293,6 +295,14 @@ export class FeedModel {
this.feed = []
}
switchFeedType(feedType: 'home' | 'suggested') {
if (this.feedType === feedType) {
return
}
this.feedType = feedType
return this.setup()
}
/**
* Load for first render
*/
@ -427,7 +437,7 @@ export class FeedModel {
* Check if new posts are available
*/
async checkForLatest() {
if (this.hasNewLatest || this.rootStore.me.follows.isEmpty) {
if (this.hasNewLatest || this.feedType === 'suggested') {
return
}
const res = await this._getFeed({limit: 1})
@ -562,30 +572,25 @@ export class FeedModel {
params: GetTimeline.QueryParams | GetAuthorFeed.QueryParams = {},
): Promise<GetTimeline.Response | GetAuthorFeed.Response> {
params = Object.assign({}, this.params, params)
if (this.feedType === 'home') {
await this.rootStore.me.follows.fetchIfNeeded()
if (this.rootStore.me.follows.isEmpty) {
const responses = await getMultipleAuthorsPosts(
this.rootStore,
sampleSize(
SUGGESTED_FOLLOWS(String(this.rootStore.agent.service)),
20,
),
params.before,
20,
)
const combinedCursor = getCombinedCursors(responses)
const finalData = mergePosts(responses, {bestOfOnly: true})
const lastHeaders = responses[responses.length - 1].headers
return {
success: true,
data: {
feed: finalData,
cursor: combinedCursor,
},
headers: lastHeaders,
}
if (this.feedType === 'suggested') {
const responses = await getMultipleAuthorsPosts(
this.rootStore,
sampleSize(SUGGESTED_FOLLOWS(String(this.rootStore.agent.service)), 20),
params.before,
20,
)
const combinedCursor = getCombinedCursors(responses)
const finalData = mergePosts(responses, {bestOfOnly: true})
const lastHeaders = responses[responses.length - 1].headers
return {
success: true,
data: {
feed: finalData,
cursor: combinedCursor,
},
headers: lastHeaders,
}
} else if (this.feedType === 'home') {
return this.rootStore.api.app.bsky.feed.getTimeline(
params as GetTimeline.QueryParams,
)

View file

@ -72,6 +72,10 @@ export class MyFollowsModel {
return !!this.followDidToRecordMap[did]
}
get numFollows() {
return Object.keys(this.followDidToRecordMap).length
}
get isEmpty() {
return Object.keys(this.followDidToRecordMap).length === 0
}

View file

@ -345,6 +345,7 @@ export class SessionModel {
)
this.setActiveSession(agent, did)
this.rootStore.shell.setOnboarding(true)
this.rootStore.log.debug('SessionModel:createAccount succeeded')
}

View file

@ -118,6 +118,7 @@ export class ShellUiModel {
activeLightbox: ProfileImageLightbox | ImagesLightbox | undefined
isComposerActive = false
composerOpts: ComposerOpts | undefined
isOnboarding = false
constructor(public rootStore: RootStoreModel) {
makeAutoObservable(this, {
@ -185,4 +186,13 @@ export class ShellUiModel {
this.isComposerActive = false
this.composerOpts = undefined
}
setOnboarding(v: boolean) {
this.isOnboarding = v
if (this.isOnboarding) {
this.rootStore.me.mainFeed.switchFeedType('suggested')
} else {
this.rootStore.me.mainFeed.switchFeedType('home')
}
}
}