New user progress guides (#4716)

* Add the animated checkmark svg

* Add progress guide list and task components

* Add ProgressGuide Toast component

* Implement progress-guide controller

* Add 7 follows to the progress guide

* Wire up action captures

* Wire up progress-guide persistence

* Trigger progress guide on account creation

* Clear the progress guide from storage on complete

* Add progress guide interstitial, put behind gate

* Fix: read progress guide state from prefs

* Some defensive type checks

* Create separate toast for completion

* List tweaks

* Only show on Discover

* Spacing and progress tweaks

* Completely hide when complete

* Capture the progress guide in local state, and only render toasts while guide is active

* Fix: ensure persisted hydrates into local state

* Gate

---------

Co-authored-by: Eric Bailey <git@esb.lol>
Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
This commit is contained in:
Paul Frazee 2024-07-03 19:05:19 -07:00 committed by GitHub
parent aa7117edb6
commit 0ed99b840d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 721 additions and 22 deletions

View file

@ -34,7 +34,11 @@ import {useSession} from '#/state/session'
import {useAnalytics} from 'lib/analytics/analytics'
import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender'
import {useTheme} from 'lib/ThemeContext'
import {SuggestedFeeds, SuggestedFollows} from '#/components/FeedInterstitials'
import {
ProgressGuide,
SuggestedFeeds,
SuggestedFollows,
} from '#/components/FeedInterstitials'
import {List, ListRef} from '../util/List'
import {PostFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn'
@ -85,12 +89,26 @@ type FeedItem =
}
slot: number
}
| {
type: 'interstitialProgressGuide'
key: string
params: {
variant: 'default' | string
}
slot: number
}
const feedInterstitialType = 'interstitialFeeds'
const followInterstitialType = 'interstitialFollows'
const progressGuideInterstitialType = 'interstitialProgressGuide'
const interstials: Record<
'following' | 'discover',
(FeedItem & {type: 'interstitialFeeds' | 'interstitialFollows'})[]
(FeedItem & {
type:
| 'interstitialFeeds'
| 'interstitialFollows'
| 'interstitialProgressGuide'
})[]
> = {
following: [
{
@ -111,6 +129,14 @@ const interstials: Record<
},
],
discover: [
{
type: progressGuideInterstitialType,
params: {
variant: 'default',
},
key: progressGuideInterstitialType,
slot: 0,
},
{
type: feedInterstitialType,
params: {
@ -336,14 +362,14 @@ let Feed = ({
if (feedType) {
for (const interstitial of interstials[feedType]) {
const feedInterstitialEnabled =
interstitial.type === feedInterstitialType &&
gate('suggested_feeds_interstitial')
const followInterstitialEnabled =
interstitial.type === followInterstitialType &&
gate('suggested_follows_interstitial')
const shouldShow =
(interstitial.type === feedInterstitialType &&
gate('suggested_feeds_interstitial')) ||
(interstitial.type === followInterstitialType &&
gate('suggested_follows_interstitial')) ||
interstitial.type === progressGuideInterstitialType
if (feedInterstitialEnabled || followInterstitialEnabled) {
if (shouldShow) {
const variant = 'default' // replace with experiment variant
const int = {
...interstitial,
@ -460,6 +486,8 @@ let Feed = ({
return <SuggestedFeeds />
} else if (item.type === followInterstitialType) {
return <SuggestedFollows />
} else if (item.type === progressGuideInterstitialType) {
return <ProgressGuide />
} else if (item.type === 'slice') {
if (item.slice.rootUri === FALLBACK_MARKER_POST.post.uri) {
// HACK