add store review prompt based on number of sessions
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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.`)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user