add store review prompt based on number of sessions

This commit is contained in:
Ansh Nanda
2023-11-16 15:02:22 -08:00
parent 6aa865ea41
commit e522f69b1e
5 changed files with 108 additions and 0 deletions
+6
View File
@@ -37,6 +37,7 @@ import * as persisted from '#/state/persisted'
import {i18n} from '@lingui/core'
import {I18nProvider} from '@lingui/react'
import {messages} from './locale/locales/en/messages'
import {listenSessionChangeForStoreReview} from './lib/store-review'
i18n.load('en', messages)
i18n.activate('en')
@@ -55,9 +56,14 @@ function InnerApp() {
listenSessionDropped(() => {
Toast.show('Sorry! Your session expired. Please log in again.')
})
const lForStoreReview = listenSessionChangeForStoreReview()
const account = persisted.get('session').currentAccount
resumeSession(account)
return () => {
lForStoreReview() // cleanup
}
}, [resumeSession])
// show nothing prior to init
+82
View File
@@ -0,0 +1,82 @@
import * as StoreReview from 'expo-store-review'
import * as persisted from '#/state/persisted'
import {AppState} from 'react-native'
import {isWeb} from '#/platform/detection'
import {logger} from '#/logger'
async function askForStoreReivew() {
if (isWeb) return
if (await StoreReview.hasAction()) {
await StoreReview.requestReview()
}
}
async function askForStoreReviewWithDelay() {
if (isWeb) return
const {lastPromptedAt, numSessions, numFollowed} =
persisted.get('storeReview')
const now = new Date()
const oneWeek = 1000 * 60 * 60 * 24 * 7
// don't prompt if we've already prompted in the last week
if (lastPromptedAt && now.getTime() - lastPromptedAt.getTime() < oneWeek) {
return
}
// prompt if user has had 100 sessions or followed 50 people
if (numSessions >= 10 || numFollowed >= 50) {
setTimeout(() => {
askForStoreReivew().then(() => {
persisted
.write('storeReview', {
completed: true,
lastPromptedAt: now,
numSessions: numSessions,
numFollowed: numFollowed,
})
.catch(e => {
logger.error('error writing store review', {error: String(e)})
})
})
}, 5000) // delay asking for 5 seconds
return
}
}
export async function incrementStoreReviewFollowed() {
if (isWeb) return
const {numFollowed, ...others} = persisted.get('storeReview')
await persisted.write('storeReview', {
numFollowed: numFollowed + 1,
...others,
})
askForStoreReviewWithDelay()
}
export async function incrementStoreReviewSessions() {
if (isWeb) return
const {numSessions, ...others} = persisted.get('storeReview')
console.log('incrementStoreReviewSessions', numSessions, others)
await persisted.write('storeReview', {
numSessions: numSessions + 1,
...others,
})
askForStoreReviewWithDelay()
}
export function listenSessionChangeForStoreReview() {
console.log('listenSessionChangeForStoreReview')
// sets up AppState listener
const l = AppState.addEventListener('change', () => {
if (AppState.currentState === 'active') {
incrementStoreReviewSessions()
}
})
return () => {
l.remove()
}
}
+6
View File
@@ -106,6 +106,12 @@ export function transform(legacy: Partial<LegacySchema>): Schema {
onboarding: {
step: legacy.onboarding?.step || defaults.onboarding.step,
},
storeReview: {
completed: false,
lastPromptedAt: undefined,
numSessions: 0,
numFollowed: 0,
},
}
}
+12
View File
@@ -39,6 +39,12 @@ export const schema = z.object({
onboarding: z.object({
step: z.string(),
}),
storeReview: z.object({
lastPromptedAt: z.date().optional(),
completed: z.boolean(),
numSessions: z.number(),
numFollowed: z.number(),
}),
})
export type Schema = z.infer<typeof schema>
@@ -67,4 +73,10 @@ export const defaults: Schema = {
onboarding: {
step: 'Home',
},
storeReview: {
lastPromptedAt: undefined,
completed: false,
numSessions: 0,
numFollowed: 0,
},
}
+2
View File
@@ -8,6 +8,7 @@ import {
useProfileUnfollowMutation,
} from '#/state/queries/profile'
import {Shadow} from '#/state/cache/types'
import {incrementStoreReviewFollowed} from '#/lib/store-review'
export function FollowButton({
unfollowedType = 'inverted',
@@ -29,6 +30,7 @@ export function FollowButton({
}
try {
await followMutation.mutateAsync({did: profile.did})
incrementStoreReviewFollowed()
} catch (e: any) {
Toast.show(`An issue occurred, please try again.`)
}