New progress guide - 10 follows (#7128)

* new follow-10 progress guide

* find follows dialog

* wip tabs

* flatlist version with search

* hardcode out jake gold

* lazy load followup suggestions

* Update src/components/ProgressGuide/FollowDialog.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* comment out replacing, enable paging

* rm autofocus

* find shadow profiles in paginated search

* clear search when press tabs

* better tab a11y

* fix label

* adjust scroll indicator insets

* do the same scroll indicator adjustment for searchable people list

* hardcode jake to just be 'tech'

* Retain state on close/reopen

* only change follow btn color when not followed

* add guide to inside dialog

* fix task alignment

* Enable contextual suggestions

* WIP: show multiple suggestions

* Rework so it animates well

* Show more items

* remove card style

* move tabs to own component

* split out header top

* scroll active tab into view

* rm log

* Improve perf a bit

* boost popular interests over alphabetical ones

* scroll active tab into view

* revert back to round buttons

* Fix overrenders of the tab bar items

* Fix unintended animation

* Scroll initial into view if needed

* Unlift state, the dialog thing breaks lifting

* Persist simply

* Fix empty state

* Fix incorrect gate exposure

* Fix another bad useGate

* Nit

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
This commit is contained in:
Samuel Newman
2024-12-17 17:13:18 +00:00
committed by GitHub
parent 32611391a3
commit 0cbb03cd14
17 changed files with 1039 additions and 47 deletions
+78 -18
View File
@@ -1,4 +1,4 @@
import React from 'react'
import React, {useMemo} from 'react'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
@@ -16,20 +16,32 @@ export enum ProgressGuideAction {
Follow = 'follow',
}
type ProgressGuideName = 'like-10-and-follow-7'
type ProgressGuideName = 'like-10-and-follow-7' | 'follow-10'
/**
* Progress Guides that extend this interface must specify their name in the `guide` field, so it can be used as a discriminated union
*/
interface BaseProgressGuide {
guide: string
guide: ProgressGuideName
isComplete: boolean
[key: string]: any
}
interface Like10AndFollow7ProgressGuide extends BaseProgressGuide {
export interface Like10AndFollow7ProgressGuide extends BaseProgressGuide {
guide: 'like-10-and-follow-7'
numLikes: number
numFollows: number
}
type ProgressGuide = Like10AndFollow7ProgressGuide | undefined
export interface Follow10ProgressGuide extends BaseProgressGuide {
guide: 'follow-10'
numFollows: number
}
export type ProgressGuide =
| Like10AndFollow7ProgressGuide
| Follow10ProgressGuide
| undefined
const ProgressGuideContext = React.createContext<ProgressGuide>(undefined)
@@ -61,15 +73,28 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
const {mutateAsync, variables, isPending} =
useSetActiveProgressGuideMutation()
const activeProgressGuide = (
isPending ? variables : preferences?.bskyAppState?.activeProgressGuide
) as ProgressGuide
const activeProgressGuide = useMemo(() => {
const rawProgressGuide = (
isPending ? variables : preferences?.bskyAppState?.activeProgressGuide
) as ProgressGuide
// ensure the unspecced attributes have the correct types
if (activeProgressGuide?.guide === 'like-10-and-follow-7') {
activeProgressGuide.numLikes = Number(activeProgressGuide.numLikes) || 0
activeProgressGuide.numFollows = Number(activeProgressGuide.numFollows) || 0
}
if (!rawProgressGuide) return undefined
// ensure the unspecced attributes have the correct types
// clone then mutate
const {...maybeWronglyTypedProgressGuide} = rawProgressGuide
if (maybeWronglyTypedProgressGuide?.guide === 'like-10-and-follow-7') {
maybeWronglyTypedProgressGuide.numLikes =
Number(maybeWronglyTypedProgressGuide.numLikes) || 0
maybeWronglyTypedProgressGuide.numFollows =
Number(maybeWronglyTypedProgressGuide.numFollows) || 0
} else if (maybeWronglyTypedProgressGuide?.guide === 'follow-10') {
maybeWronglyTypedProgressGuide.numFollows =
Number(maybeWronglyTypedProgressGuide.numFollows) || 0
}
return maybeWronglyTypedProgressGuide
}, [isPending, variables, preferences])
const [localGuideState, setLocalGuideState] =
React.useState<ProgressGuide>(undefined)
@@ -82,7 +107,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
const firstLikeToastRef = React.useRef<ProgressGuideToastRef | null>(null)
const fifthLikeToastRef = React.useRef<ProgressGuideToastRef | null>(null)
const tenthLikeToastRef = React.useRef<ProgressGuideToastRef | null>(null)
const guideCompleteToastRef = React.useRef<ProgressGuideToastRef | null>(null)
const fifthFollowToastRef = React.useRef<ProgressGuideToastRef | null>(null)
const tenthFollowToastRef = React.useRef<ProgressGuideToastRef | null>(null)
const controls = React.useMemo(() => {
return {
@@ -93,7 +120,15 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
numLikes: 0,
numFollows: 0,
isComplete: false,
}
} satisfies ProgressGuide
setLocalGuideState(guideObj)
mutateAsync(guideObj)
} else if (guide === 'follow-10') {
const guideObj = {
guide: 'follow-10',
numFollows: 0,
isComplete: false,
} satisfies ProgressGuide
setLocalGuideState(guideObj)
mutateAsync(guideObj)
}
@@ -137,6 +172,26 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
isComplete: true,
}
}
} else if (guide?.guide === 'follow-10') {
if (action === ProgressGuideAction.Follow) {
guide = {
...guide,
numFollows: (Number(guide.numFollows) || 0) + count,
}
if (guide.numFollows === 5) {
fifthFollowToastRef.current?.open()
}
if (guide.numFollows === 10) {
tenthFollowToastRef.current?.open()
}
}
if (Number(guide.numFollows) >= 10) {
guide = {
...guide,
isComplete: true,
}
}
}
setLocalGuideState(guide)
@@ -167,9 +222,14 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
subtitle={_(msg`The Discover feed now knows what you like`)}
/>
<ProgressGuideToast
ref={guideCompleteToastRef}
title={_(msg`Algorithm training complete!`)}
subtitle={_(msg`The Discover feed now knows what you like`)}
ref={fifthFollowToastRef}
title={_(msg`Half way there!`)}
subtitle={_(msg`Follow 10 accounts`)}
/>
<ProgressGuideToast
ref={tenthFollowToastRef}
title={_(msg`Task complete - 10 follows!`)}
subtitle={_(msg`You've found some people to follow`)}
/>
</>
)}