[Perf - part 1] Hoist service config query (#8812)
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import {createContext, useContext, useMemo} from 'react'
|
||||
|
||||
import {BSKY_SERVICE} from '#/lib/constants'
|
||||
import {getHostnameFromUrl} from '#/lib/strings/url-helpers'
|
||||
import {STALE} from '#/state/queries'
|
||||
import {useProfileQuery} from '#/state/queries/profile'
|
||||
import {useCheckEmailConfirmed} from '#/state/service-config'
|
||||
import {useSession} from '#/state/session'
|
||||
|
||||
type EmailVerificationContext = {
|
||||
needsEmailVerification: boolean
|
||||
}
|
||||
|
||||
const EmailVerificationContext = createContext<EmailVerificationContext | null>(
|
||||
null,
|
||||
)
|
||||
EmailVerificationContext.displayName = 'EmailVerificationContext'
|
||||
|
||||
export function Provider({children}: {children: React.ReactNode}) {
|
||||
const {currentAccount} = useSession()
|
||||
|
||||
const {data: profile} = useProfileQuery({
|
||||
did: currentAccount?.did,
|
||||
staleTime: STALE.INFINITY,
|
||||
})
|
||||
|
||||
const checkEmailConfirmed = useCheckEmailConfirmed()
|
||||
|
||||
// Date set for 11 AM PST on the 18th of November
|
||||
const isNewEnough =
|
||||
!!profile?.createdAt &&
|
||||
Date.parse(profile.createdAt) >= Date.parse('2024-11-18T19:00:00.000Z')
|
||||
|
||||
const isSelfHost =
|
||||
currentAccount &&
|
||||
getHostnameFromUrl(currentAccount.service) !==
|
||||
getHostnameFromUrl(BSKY_SERVICE)
|
||||
|
||||
const needsEmailVerification =
|
||||
!isSelfHost &&
|
||||
checkEmailConfirmed &&
|
||||
!currentAccount?.emailConfirmed &&
|
||||
isNewEnough
|
||||
|
||||
const value = useMemo(
|
||||
() => ({needsEmailVerification}),
|
||||
[needsEmailVerification],
|
||||
)
|
||||
|
||||
return (
|
||||
<EmailVerificationContext.Provider value={value}>
|
||||
{children}
|
||||
</EmailVerificationContext.Provider>
|
||||
)
|
||||
}
|
||||
Provider.displayName = 'EmailVerificationProvider'
|
||||
|
||||
export function useEmail() {
|
||||
const ctx = useContext(EmailVerificationContext)
|
||||
if (!ctx) {
|
||||
throw new Error('useEmail must be used within a EmailVerificationProvider')
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import {useQuery} from '@tanstack/react-query'
|
||||
|
||||
interface ServiceConfig {
|
||||
checkEmailConfirmed: boolean
|
||||
}
|
||||
|
||||
export function useServiceConfigQuery() {
|
||||
return useQuery({
|
||||
queryKey: ['service-config'],
|
||||
queryFn: async () => {
|
||||
const res = await fetch(
|
||||
'https://api.bsky.app/xrpc/app.bsky.unspecced.getConfig',
|
||||
)
|
||||
if (!res.ok) {
|
||||
return {
|
||||
checkEmailConfirmed: false,
|
||||
}
|
||||
}
|
||||
|
||||
const json = await res.json()
|
||||
return json as ServiceConfig
|
||||
},
|
||||
staleTime: 5 * 60 * 1000,
|
||||
})
|
||||
}
|
||||
@@ -21,6 +21,8 @@ TrendingContext.displayName = 'TrendingContext'
|
||||
const LiveNowContext = createContext<LiveNowContext | null>(null)
|
||||
LiveNowContext.displayName = 'LiveNowContext'
|
||||
|
||||
const CheckEmailConfirmedContext = createContext<boolean | null>(null)
|
||||
|
||||
export function Provider({children}: {children: React.ReactNode}) {
|
||||
const langPrefs = useLanguagePrefs()
|
||||
const {data: config, isLoading: isInitialLoad} = useServiceConfigQuery()
|
||||
@@ -61,10 +63,16 @@ export function Provider({children}: {children: React.ReactNode}) {
|
||||
|
||||
const liveNow = useMemo<LiveNowContext>(() => config?.liveNow ?? [], [config])
|
||||
|
||||
// probably true, so default to true when loading
|
||||
// if the call fails, the query will set it to false for us
|
||||
const checkEmailConfirmed = config?.checkEmailConfirmed ?? true
|
||||
|
||||
return (
|
||||
<TrendingContext.Provider value={trending}>
|
||||
<LiveNowContext.Provider value={liveNow}>
|
||||
{children}
|
||||
<CheckEmailConfirmedContext.Provider value={checkEmailConfirmed}>
|
||||
{children}
|
||||
</CheckEmailConfirmedContext.Provider>
|
||||
</LiveNowContext.Provider>
|
||||
</TrendingContext.Provider>
|
||||
)
|
||||
@@ -78,7 +86,7 @@ export function useLiveNowConfig() {
|
||||
const ctx = useContext(LiveNowContext)
|
||||
if (!ctx) {
|
||||
throw new Error(
|
||||
'useLiveNowConfig must be used within a LiveNowConfigProvider',
|
||||
'useLiveNowConfig must be used within a ServiceConfigManager',
|
||||
)
|
||||
}
|
||||
return ctx
|
||||
@@ -88,3 +96,13 @@ export function useCanGoLive(did?: string) {
|
||||
const config = useLiveNowConfig()
|
||||
return !!config.find(cfg => cfg.did === did)
|
||||
}
|
||||
|
||||
export function useCheckEmailConfirmed() {
|
||||
const ctx = useContext(CheckEmailConfirmedContext)
|
||||
if (ctx === null) {
|
||||
throw new Error(
|
||||
'useCheckEmailConfirmed must be used within a ServiceConfigManager',
|
||||
)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user