Move reminders to new persisted state layer (#1834)
parent
96d8faf4b0
commit
2acc88e78d
|
@ -20,7 +20,6 @@ import {PreferencesModel} from './ui/preferences'
|
|||
import {resetToTab} from '../../Navigation'
|
||||
import {ImageSizesCache} from './cache/image-sizes'
|
||||
import {MutedThreads} from './muted-threads'
|
||||
import {Reminders} from './ui/reminders'
|
||||
import {reset as resetNavigation} from '../../Navigation'
|
||||
import {logger} from '#/logger'
|
||||
|
||||
|
@ -53,7 +52,6 @@ export class RootStoreModel {
|
|||
linkMetas = new LinkMetasCache(this)
|
||||
imageSizes = new ImageSizesCache()
|
||||
mutedThreads = new MutedThreads()
|
||||
reminders = new Reminders(this)
|
||||
|
||||
constructor(agent: BskyAgent) {
|
||||
this.agent = agent
|
||||
|
@ -77,7 +75,6 @@ export class RootStoreModel {
|
|||
preferences: this.preferences.serialize(),
|
||||
invitedUsers: this.invitedUsers.serialize(),
|
||||
mutedThreads: this.mutedThreads.serialize(),
|
||||
reminders: this.reminders.serialize(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,9 +104,6 @@ export class RootStoreModel {
|
|||
if (hasProp(v, 'mutedThreads')) {
|
||||
this.mutedThreads.hydrate(v.mutedThreads)
|
||||
}
|
||||
if (hasProp(v, 'reminders')) {
|
||||
this.reminders.hydrate(v.reminders)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
import {makeAutoObservable} from 'mobx'
|
||||
import {RootStoreModel} from '../root-store'
|
||||
|
||||
export class Reminders {
|
||||
constructor(public rootStore: RootStoreModel) {
|
||||
makeAutoObservable(
|
||||
this,
|
||||
{serialize: false, hydrate: false},
|
||||
{autoBind: true},
|
||||
)
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return {}
|
||||
}
|
||||
|
||||
hydrate(_v: unknown) {}
|
||||
|
||||
get shouldRequestEmailConfirmation() {
|
||||
return false
|
||||
}
|
||||
|
||||
setEmailConfirmationRequested() {}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
import {makeAutoObservable} from 'mobx'
|
||||
import {isObj, hasProp} from 'lib/type-guards'
|
||||
import {RootStoreModel} from '../root-store'
|
||||
import {toHashCode} from 'lib/strings/helpers'
|
||||
|
||||
export class Reminders {
|
||||
lastEmailConfirm: Date | null = null
|
||||
|
||||
constructor(public rootStore: RootStoreModel) {
|
||||
makeAutoObservable(
|
||||
this,
|
||||
{serialize: false, hydrate: false},
|
||||
{autoBind: true},
|
||||
)
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return {
|
||||
lastEmailConfirm: this.lastEmailConfirm
|
||||
? this.lastEmailConfirm.toISOString()
|
||||
: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
hydrate(v: unknown) {
|
||||
if (
|
||||
isObj(v) &&
|
||||
hasProp(v, 'lastEmailConfirm') &&
|
||||
typeof v.lastEmailConfirm === 'string'
|
||||
) {
|
||||
this.lastEmailConfirm = new Date(v.lastEmailConfirm)
|
||||
}
|
||||
}
|
||||
|
||||
get shouldRequestEmailConfirmation() {
|
||||
const sess = this.rootStore.session.currentSession
|
||||
if (!sess) {
|
||||
return false
|
||||
}
|
||||
if (sess.emailConfirmed) {
|
||||
return false
|
||||
}
|
||||
if (this.rootStore.onboarding.isActive) {
|
||||
return false
|
||||
}
|
||||
// only prompt once
|
||||
if (this.lastEmailConfirm) {
|
||||
return false
|
||||
}
|
||||
const today = new Date()
|
||||
// shard the users into 2 day of the week buckets
|
||||
// (this is to avoid a sudden influx of email updates when
|
||||
// this feature rolls out)
|
||||
const code = toHashCode(sess.did) % 7
|
||||
if (code !== today.getDay() && code !== (today.getDay() + 1) % 7) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
setEmailConfirmationRequested() {
|
||||
this.lastEmailConfirm = new Date()
|
||||
}
|
||||
}
|
|
@ -7,6 +7,10 @@ import {ImageModel} from '../media/image'
|
|||
import {ListModel} from '../content/list'
|
||||
import {GalleryModel} from '../media/gallery'
|
||||
import {StyleProp, ViewStyle} from 'react-native'
|
||||
import {
|
||||
shouldRequestEmailConfirmation,
|
||||
setEmailConfirmationRequested,
|
||||
} from '#/state/shell/reminders'
|
||||
|
||||
export type ColorMode = 'system' | 'light' | 'dark'
|
||||
|
||||
|
@ -358,9 +362,14 @@ export class ShellUiModel {
|
|||
|
||||
setupLoginModals() {
|
||||
this.rootStore.onSessionReady(() => {
|
||||
if (this.rootStore.reminders.shouldRequestEmailConfirmation) {
|
||||
if (
|
||||
shouldRequestEmailConfirmation(
|
||||
this.rootStore.session,
|
||||
this.rootStore.onboarding,
|
||||
)
|
||||
) {
|
||||
this.openModal({name: 'verify-email', showReminder: true})
|
||||
this.rootStore.reminders.setEmailConfirmationRequested()
|
||||
setEmailConfirmationRequested()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -76,9 +76,9 @@ export function transform(legacy: LegacySchema): Schema {
|
|||
defaults.session.currentAccount,
|
||||
},
|
||||
reminders: {
|
||||
lastEmailConfirmReminder:
|
||||
lastEmailConfirm:
|
||||
legacy.reminders.lastEmailConfirm ||
|
||||
defaults.reminders.lastEmailConfirmReminder,
|
||||
defaults.reminders.lastEmailConfirm,
|
||||
},
|
||||
languagePrefs: {
|
||||
primaryLanguage:
|
||||
|
|
|
@ -19,7 +19,7 @@ export const schema = z.object({
|
|||
currentAccount: accountSchema.optional(),
|
||||
}),
|
||||
reminders: z.object({
|
||||
lastEmailConfirmReminder: z.string().optional(),
|
||||
lastEmailConfirm: z.string().optional(),
|
||||
}),
|
||||
languagePrefs: z.object({
|
||||
primaryLanguage: z.string(), // should move to server
|
||||
|
@ -46,7 +46,7 @@ export const defaults: Schema = {
|
|||
currentAccount: undefined,
|
||||
},
|
||||
reminders: {
|
||||
lastEmailConfirmReminder: undefined,
|
||||
lastEmailConfirm: undefined,
|
||||
},
|
||||
languagePrefs: {
|
||||
primaryLanguage: deviceLocales[0] || 'en',
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import {OnboardingModel} from '../models/discovery/onboarding'
|
||||
import {SessionModel} from '../models/session'
|
||||
|
||||
export function shouldRequestEmailConfirmation(
|
||||
_session: SessionModel,
|
||||
_onboarding: OnboardingModel,
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
export function setEmailConfirmationRequested() {}
|
|
@ -0,0 +1,40 @@
|
|||
import * as persisted from '#/state/persisted'
|
||||
import {OnboardingModel} from '../models/discovery/onboarding'
|
||||
import {SessionModel} from '../models/session'
|
||||
import {toHashCode} from 'lib/strings/helpers'
|
||||
|
||||
export function shouldRequestEmailConfirmation(
|
||||
session: SessionModel,
|
||||
onboarding: OnboardingModel,
|
||||
) {
|
||||
const sess = session.currentSession
|
||||
if (!sess) {
|
||||
return false
|
||||
}
|
||||
if (sess.emailConfirmed) {
|
||||
return false
|
||||
}
|
||||
if (onboarding.isActive) {
|
||||
return false
|
||||
}
|
||||
// only prompt once
|
||||
if (persisted.get('reminders').lastEmailConfirm) {
|
||||
return false
|
||||
}
|
||||
const today = new Date()
|
||||
// shard the users into 2 day of the week buckets
|
||||
// (this is to avoid a sudden influx of email updates when
|
||||
// this feature rolls out)
|
||||
const code = toHashCode(sess.did) % 7
|
||||
if (code !== today.getDay() && code !== (today.getDay() + 1) % 7) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export function setEmailConfirmationRequested() {
|
||||
persisted.write('reminders', {
|
||||
...persisted.get('reminders'),
|
||||
lastEmailConfirm: new Date().toISOString(),
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue