diff --git a/src/App.native.tsx b/src/App.native.tsx
index 18af744097..f0dde6ee1a 100644
--- a/src/App.native.tsx
+++ b/src/App.native.tsx
@@ -45,6 +45,7 @@ import {
import {readLastActiveAccount} from '#/state/session/util'
import {Provider as ShellStateProvider} from '#/state/shell'
import {Provider as LoggedOutViewProvider} from '#/state/shell/logged-out'
+import {Provider as ProgressGuideProvider} from '#/state/shell/progress-guide'
import {Provider as SelectedFeedProvider} from '#/state/shell/selected-feed'
import {Provider as StarterPackProvider} from '#/state/shell/starter-pack'
import {TestCtrls} from '#/view/com/testing/TestCtrls'
@@ -119,10 +120,13 @@ function InnerApp() {
-
-
-
-
+
+
+
+
+
+
diff --git a/src/App.web.tsx b/src/App.web.tsx
index f45806e4d2..eb4a925d07 100644
--- a/src/App.web.tsx
+++ b/src/App.web.tsx
@@ -34,6 +34,7 @@ import {
import {readLastActiveAccount} from '#/state/session/util'
import {Provider as ShellStateProvider} from '#/state/shell'
import {Provider as LoggedOutViewProvider} from '#/state/shell/logged-out'
+import {Provider as ProgressGuideProvider} from '#/state/shell/progress-guide'
import {Provider as SelectedFeedProvider} from '#/state/shell/selected-feed'
import {Provider as StarterPackProvider} from '#/state/shell/starter-pack'
import * as Toast from '#/view/com/util/Toast'
@@ -104,7 +105,9 @@ function InnerApp() {
-
+
+
+
diff --git a/src/components/ProgressGuide/List.tsx b/src/components/ProgressGuide/List.tsx
index 489e083dd8..05f8cb25b2 100644
--- a/src/components/ProgressGuide/List.tsx
+++ b/src/components/ProgressGuide/List.tsx
@@ -1,58 +1,61 @@
import React from 'react'
-import {View} from 'react-native'
+import {StyleProp, View, ViewStyle} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
+import {
+ ProgressGuideAction,
+ ProgressGuideName,
+ useProgressGuide,
+ useProgressGuideControls,
+} from '#/state/shell/progress-guide'
import {atoms as a, useTheme} from '#/alf'
-import {Button, ButtonIcon} from '../Button'
-import {TimesLarge_Stroke2_Corner0_Rounded as Times} from '../icons/Times'
-import {Text} from '../Typography'
+import {Button, ButtonIcon} from '#/components/Button'
+import {TimesLarge_Stroke2_Corner0_Rounded as Times} from '#/components/icons/Times'
+import {Text} from '#/components/Typography'
import {ProgressGuideTask} from './Task'
-export function ProgressGuideList() {
+export function ProgressGuideList({style}: {style: StyleProp}) {
const t = useTheme()
const {_} = useLingui()
+ const guide = useProgressGuide(ProgressGuideName.Like10Posts)
+ const {captureAction, endProgressGuide} = useProgressGuideControls()
- const [numLikes, setNumLikes] = React.useState(0)
- const [numFollows, setNumFollows] = React.useState(0)
-
- // DEBUG
React.useEffect(() => {
- const i = setInterval(() => {
- setNumLikes(v => (v >= 10 ? 0 : v + 1))
- setNumFollows(v => (v >= 7 ? 0 : v + 1))
- }, 1000)
- return () => {
- clearInterval(i)
- }
- }, [setNumLikes])
+ const i = setInterval(() => captureAction(ProgressGuideAction.Like), 2e3)
+ return () => clearInterval(i)
+ }, [captureAction])
- return (
-
-
-
- GET STARTED
-
-
+ if (guide?.guide === ProgressGuideName.Like10Posts) {
+ return (
+
+
+
+ Get started
+
+
+
+
-
-
-
- )
+ )
+ }
+ return null
}
diff --git a/src/components/ProgressGuide/Toast.tsx b/src/components/ProgressGuide/Toast.tsx
index 3d040df5f5..346312af51 100644
--- a/src/components/ProgressGuide/Toast.tsx
+++ b/src/components/ProgressGuide/Toast.tsx
@@ -1,5 +1,5 @@
import React, {useImperativeHandle} from 'react'
-import {Keyboard, Pressable, View} from 'react-native'
+import {Pressable, useWindowDimensions, View} from 'react-native'
import Animated, {
Easing,
runOnJS,
@@ -11,6 +11,7 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
+import {isWeb} from '#/platform/detection'
import {atoms as a, useTheme} from '#/alf'
import {Portal} from '#/components/Portal'
import {AnimatedCheck, AnimatedCheckRef} from '../anim/AnimatedCheck'
@@ -39,6 +40,7 @@ export const ProgressGuideToast = React.forwardRef<
const opacity = useSharedValue(0)
const animatedCheckRef = React.useRef(null)
const timeoutRef = React.useRef()
+ const winDim = useWindowDimensions()
/**
* Methods
@@ -97,6 +99,20 @@ export const ProgressGuideToast = React.forwardRef<
[open, close],
)
+ const containerStyle = React.useMemo(() => {
+ let left = 10
+ let right = 10
+ if (isWeb && winDim.width > 400) {
+ left = right = (winDim.width - 380) / 2
+ }
+ return {
+ position: isWeb ? 'fixed' : 'absolute',
+ top: 0,
+ left,
+ right,
+ }
+ }, [winDim.width])
+
const animatedStyle = useAnimatedStyle(() => ({
transform: [{translateY: translateY.value}],
opacity: opacity.value,
@@ -105,45 +121,48 @@ export const ProgressGuideToast = React.forwardRef<
return (
isOpen && (
- Keyboard.dismiss()}>
-
-
-
-
- {title}
- {subtitle && (
-
- {subtitle}
-
- )}
-
-
-
-
+
+
+
+
+ {title}
+ {subtitle && (
+
+ {subtitle}
+
+ )}
+
+
+
)
)
diff --git a/src/state/shell/progress-guide.tsx b/src/state/shell/progress-guide.tsx
new file mode 100644
index 0000000000..b759a0a884
--- /dev/null
+++ b/src/state/shell/progress-guide.tsx
@@ -0,0 +1,137 @@
+import React from 'react'
+import {msg} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+
+import {
+ ProgressGuideToast,
+ ProgressGuideToastRef,
+} from '#/components/ProgressGuide/Toast'
+
+export enum ProgressGuideAction {
+ Like = 'like',
+}
+
+export enum ProgressGuideName {
+ Like10Posts = 'like-10-posts',
+}
+
+interface BaseProgressGuide {
+ guide: ProgressGuideName
+ isComplete: boolean
+}
+
+interface Like10PostsProgressGuide extends BaseProgressGuide {
+ guide: ProgressGuideName.Like10Posts
+ numLikes: number
+}
+
+type ProgressGuide = Like10PostsProgressGuide | undefined
+
+const ProgressGuideContext = React.createContext(undefined)
+
+const ProgressGuideControlContext = React.createContext<{
+ startProgressGuide(guide: ProgressGuideName): void
+ endProgressGuide(): void
+ captureAction(action: ProgressGuideAction): void
+}>({
+ startProgressGuide: (_guide: ProgressGuideName) => {},
+ endProgressGuide: () => {},
+ captureAction: (_action: ProgressGuideAction) => {},
+})
+
+export function useProgressGuide(guide: ProgressGuideName) {
+ const ctx = React.useContext(ProgressGuideContext)
+ if (ctx?.guide === guide) {
+ return ctx
+ }
+ return undefined
+}
+
+export function useProgressGuideControls() {
+ return React.useContext(ProgressGuideControlContext)
+}
+
+export function Provider({children}: React.PropsWithChildren<{}>) {
+ const {_} = useLingui()
+
+ const [activeProgressGuide, setActiveProgressGuide] =
+ React.useState({
+ guide: ProgressGuideName.Like10Posts,
+ numLikes: 0,
+ isComplete: false,
+ })
+
+ const firstLikeToastRef = React.useRef(null)
+ const fifthLikeToastRef = React.useRef(null)
+ const tenthLikeToastRef = React.useRef(null)
+
+ const controls = React.useMemo(() => {
+ return {
+ startProgressGuide(guide: ProgressGuideName) {
+ if (guide === ProgressGuideName.Like10Posts) {
+ setActiveProgressGuide({
+ guide: ProgressGuideName.Like10Posts,
+ numLikes: 0,
+ isComplete: false,
+ })
+ }
+ },
+
+ endProgressGuide() {
+ setActiveProgressGuide(undefined)
+ },
+
+ captureAction(action: ProgressGuideAction) {
+ let guide = activeProgressGuide
+ if (guide?.isComplete) {
+ return
+ }
+ if (guide?.guide === ProgressGuideName.Like10Posts) {
+ if (action === ProgressGuideAction.Like) {
+ guide = {
+ ...guide,
+ numLikes: (guide.numLikes || 0) + 1,
+ }
+ if (guide.numLikes === 1) {
+ firstLikeToastRef.current?.open()
+ }
+ if (guide.numLikes === 5) {
+ fifthLikeToastRef.current?.open()
+ }
+ if (guide.numLikes === 10) {
+ tenthLikeToastRef.current?.open()
+ guide = {
+ ...guide,
+ isComplete: true,
+ }
+ }
+ }
+ }
+ setActiveProgressGuide(guide)
+ },
+ }
+ }, [activeProgressGuide, setActiveProgressGuide])
+
+ return (
+
+
+ {children}
+
+
+
+
+
+ )
+}
diff --git a/src/view/com/home/HomeHeaderLayoutMobile.tsx b/src/view/com/home/HomeHeaderLayoutMobile.tsx
index ed353cf168..168340d7af 100644
--- a/src/view/com/home/HomeHeaderLayoutMobile.tsx
+++ b/src/view/com/home/HomeHeaderLayoutMobile.tsx
@@ -6,6 +6,10 @@ import {useLingui} from '@lingui/react'
import {useSession} from '#/state/session'
import {useSetDrawerOpen} from '#/state/shell/drawer-open'
+import {
+ ProgressGuideAction,
+ useProgressGuideControls,
+} from '#/state/shell/progress-guide'
import {useShellLayout} from '#/state/shell/shell-layout'
import {HITSLOP_10} from 'lib/constants'
import {useMinimalShellHeaderTransform} from 'lib/hooks/useMinimalShellTransform'
@@ -34,11 +38,19 @@ export function HomeHeaderLayoutMobile({
const {headerHeight} = useShellLayout()
const headerMinimalShellTransform = useMinimalShellHeaderTransform()
const {hasSession} = useSession()
+ const {captureAction} = useProgressGuideControls()
const onPressAvi = React.useCallback(() => {
setDrawerOpen(true)
}, [setDrawerOpen])
+ React.useEffect(() => {
+ const i = setInterval(() => captureAction(ProgressGuideAction.Like), 1000)
+ return () => {
+ clearInterval(i)
+ }
+ }, [captureAction])
+
return (
{hasSession && (
-
-
-
+ <>
+
+
+
+
+ >
)}
>
)}