Improve birthdate handling (#10477)

This commit is contained in:
DS Boyce
2026-05-13 13:52:59 -07:00
committed by GitHub
parent d20df78f7e
commit b41d0ad97d
4 changed files with 29 additions and 36 deletions
-5
View File
@@ -264,11 +264,6 @@
"count": 1 "count": 1
} }
}, },
"src/lib/hooks/useCleanError.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 1
}
},
"src/lib/hooks/useNonReactiveCallback.ts": { "src/lib/hooks/useNonReactiveCallback.ts": {
"@typescript-eslint/no-explicit-any": { "@typescript-eslint/no-explicit-any": {
"count": 1 "count": 1
+13 -9
View File
@@ -37,6 +37,14 @@ export function BirthDateSettingsDialog({
const isBirthdateUpdateAllowed = useIsBirthdateUpdateAllowed() const isBirthdateUpdateAllowed = useIsBirthdateUpdateAllowed()
const {currentAccount} = useSession() const {currentAccount} = useSession()
const isUsingAppPassword = isAppPassword(currentAccount?.accessJwt || '') const isUsingAppPassword = isAppPassword(currentAccount?.accessJwt || '')
const cleanError = useCleanError()
const defaultErrorMessage = l`We were unable to load your birthdate preferences. Please try again.`
const fetchErrorMessage = useMemo(() => {
if (error) {
const {raw, clean} = cleanError(error)
return clean || raw
}
}, [error, cleanError])
return ( return (
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}> <Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
@@ -58,12 +66,9 @@ export function BirthDateSettingsDialog({
{isLoading ? ( {isLoading ? (
<Loader size="xl" /> <Loader size="xl" />
) : error || !preferences ? ( ) : fetchErrorMessage || !preferences ? (
<ErrorMessage <ErrorMessage
message={ message={fetchErrorMessage || defaultErrorMessage}
error?.toString() ||
l`We were unable to load your birthdate preferences. Please try again.`
}
style={[a.rounded_sm]} style={[a.rounded_sm]}
/> />
) : isUsingAppPassword ? ( ) : isUsingAppPassword ? (
@@ -123,12 +128,11 @@ function BirthdayInner({
const cleanError = useCleanError() const cleanError = useCleanError()
const [date, setDate] = useState(preferences.birthDate || getDateAgo(18)) const [date, setDate] = useState(preferences.birthDate || getDateAgo(18))
const {isPending, error, mutateAsync: setBirthDate} = useBirthdateMutation() const {isPending, error, mutateAsync: setBirthDate} = useBirthdateMutation()
const hasChanged = date !== preferences.birthDate const hasChanged = date?.getTime() !== preferences.birthDate?.getTime()
const errorMessage = useMemo(() => { const errorMessage = useMemo(() => {
if (error) { if (error) {
const e = error as Error const {raw, clean} = cleanError(error)
const {raw, clean} = cleanError(e) return clean || raw
return clean || raw || e.toString()
} }
}, [error, cleanError]) }, [error, cleanError])
+15 -21
View File
@@ -1,6 +1,5 @@
import {useCallback} from 'react' import {useCallback} from 'react'
import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react/macro'
import {useLingui} from '@lingui/react'
type CleanedError = { type CleanedError = {
raw: string | undefined raw: string | undefined
@@ -8,9 +7,9 @@ type CleanedError = {
} }
export function useCleanError() { export function useCleanError() {
const {_} = useLingui() const {t: l} = useLingui()
return useCallback<(error?: any) => CleanedError>( return useCallback<(error?: unknown) => CleanedError>(
error => { error => {
if (!error) if (!error)
return { return {
@@ -18,14 +17,17 @@ export function useCleanError() {
clean: undefined, clean: undefined,
} }
let raw = error.toString() let raw =
error instanceof Error
? error.message
: typeof error === 'string'
? error
: JSON.stringify(error)
if (isNetworkError(raw)) { if (isNetworkError(raw)) {
return { return {
raw, raw,
clean: _( clean: l`Unable to connect. Please check your internet connection and try again.`,
msg`Unable to connect. Please check your internet connection and try again.`,
),
} }
} }
@@ -36,9 +38,7 @@ export function useCleanError() {
) { ) {
return { return {
raw, raw,
clean: _( clean: l`The server appears to be experiencing issues. Please try again in a few moments.`,
msg`The server appears to be experiencing issues. Please try again in a few moments.`,
),
} }
} }
@@ -51,27 +51,21 @@ export function useCleanError() {
) { ) {
return { return {
raw, raw,
clean: _( clean: l`You cannot update your birthdate while using an app password. Please sign in with your main password to update your birthdate.`,
msg`You cannot update your birthdate while using an app password. Please sign in with your main password to update your birthdate.`,
),
} }
} }
if (raw.includes('Bad token scope') || raw.includes('Bad token method')) { if (raw.includes('Bad token scope') || raw.includes('Bad token method')) {
return { return {
raw, raw,
clean: _( clean: l`This feature is not available while using an app password. Please sign in with your main password.`,
msg`This feature is not available while using an app password. Please sign in with your main password.`,
),
} }
} }
if (raw.includes('Rate Limit Exceeded')) { if (raw.includes('Rate Limit Exceeded')) {
return { return {
raw, raw,
clean: _( clean: l`You've reached the maximum number of requests allowed. Please try again later.`,
msg`You've reached the maximum number of requests allowed. Please try again later.`,
),
} }
} }
@@ -84,7 +78,7 @@ export function useCleanError() {
clean: undefined, clean: undefined,
} }
}, },
[_], [l],
) )
} }
+1 -1
View File
@@ -53,7 +53,7 @@ export function usePreferencesQuery() {
const res = await agent.getPreferences() const res = await agent.getPreferences()
// save to local storage to ensure there are labels on initial requests // save to local storage to ensure there are labels on initial requests
saveLabelers( void saveLabelers(
agent.did, agent.did,
res.moderationPrefs.labelers.map(l => l.did), res.moderationPrefs.labelers.map(l => l.did),
) )