about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2023-12-28 16:13:51 -0600
committerGitHub <noreply@github.com>2023-12-28 14:13:51 -0800
commit705f9b61efebe8ca0d044f1a53586b6fe4614195 (patch)
treea1ed4e9d483377a01c4cbefa5b6e1c8f657e03cc
parent23c9c8977b73ae86f0099012ec372a4bccc9741f (diff)
downloadvoidsky-705f9b61efebe8ca0d044f1a53586b6fe4614195.tar.zst
Handle birth dates as UTC, handle locale formatting (#2363)
* Enforce UTC for birthdate picker

* Handle locales

* Remove log

* Add a second snap point to the date input in case text is zoomed

* Guard against bad dates

* Log message

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
-rw-r--r--src/view/com/auth/create/Step2.tsx18
-rw-r--r--src/view/com/modals/BirthDateSettings.tsx3
-rw-r--r--src/view/com/util/forms/DateInput.tsx13
3 files changed, 31 insertions, 3 deletions
diff --git a/src/view/com/auth/create/Step2.tsx b/src/view/com/auth/create/Step2.tsx
index 89fd070ad..123b5f662 100644
--- a/src/view/com/auth/create/Step2.tsx
+++ b/src/view/com/auth/create/Step2.tsx
@@ -13,6 +13,17 @@ import {isWeb} from 'platform/detection'
 import {Trans, msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useModalControls} from '#/state/modals'
+import {logger} from '#/logger'
+
+function sanitizeDate(date: Date): Date {
+  if (!date || date.toString() === 'Invalid Date') {
+    logger.error(`Create account: handled invalid date for birthDate`, {
+      hasDate: !!date,
+    })
+    return new Date()
+  }
+  return date
+}
 
 /** STEP 2: Your account
  * @field Invite code or waitlist
@@ -38,6 +49,10 @@ export function Step2({
     openModal({name: 'waitlist'})
   }, [openModal])
 
+  const birthDate = React.useMemo(() => {
+    return sanitizeDate(uiState.birthDate)
+  }, [uiState.birthDate])
+
   return (
     <View>
       <StepHeader step="2" title={_(msg`Your account`)} />
@@ -122,8 +137,9 @@ export function Step2({
               <Trans>Your birth date</Trans>
             </Text>
             <DateInput
+              handleAsUTC
               testID="birthdayInput"
-              value={uiState.birthDate}
+              value={birthDate}
               onChange={value => uiDispatch({type: 'set-birth-date', value})}
               buttonType="default-light"
               buttonStyle={[pal.border, styles.dateInputButton]}
diff --git a/src/view/com/modals/BirthDateSettings.tsx b/src/view/com/modals/BirthDateSettings.tsx
index c78f06ed4..1505d224f 100644
--- a/src/view/com/modals/BirthDateSettings.tsx
+++ b/src/view/com/modals/BirthDateSettings.tsx
@@ -23,7 +23,7 @@ import {
 } from '#/state/queries/preferences'
 import {logger} from '#/logger'
 
-export const snapPoints = ['50%']
+export const snapPoints = ['50%', '90%']
 
 function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) {
   const pal = usePalette('default')
@@ -63,6 +63,7 @@ function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) {
 
       <View>
         <DateInput
+          handleAsUTC
           testID="birthdayInput"
           value={date}
           onChange={setDate}
diff --git a/src/view/com/util/forms/DateInput.tsx b/src/view/com/util/forms/DateInput.tsx
index 4aa5cb610..c5f0afc8f 100644
--- a/src/view/com/util/forms/DateInput.tsx
+++ b/src/view/com/util/forms/DateInput.tsx
@@ -13,6 +13,9 @@ import {Text} from '../text/Text'
 import {TypographyVariant} from 'lib/ThemeContext'
 import {useTheme} from 'lib/ThemeContext'
 import {usePalette} from 'lib/hooks/usePalette'
+import {getLocales} from 'expo-localization'
+
+const LOCALE = getLocales()[0]
 
 interface Props {
   testID?: string
@@ -25,6 +28,7 @@ interface Props {
   accessibilityLabel: string
   accessibilityHint: string
   accessibilityLabelledBy?: string
+  handleAsUTC?: boolean
 }
 
 export function DateInput(props: Props) {
@@ -32,6 +36,12 @@ export function DateInput(props: Props) {
   const theme = useTheme()
   const pal = usePalette('default')
 
+  const formatter = React.useMemo(() => {
+    return new Intl.DateTimeFormat(LOCALE.languageTag, {
+      timeZone: props.handleAsUTC ? 'UTC' : undefined,
+    })
+  }, [props.handleAsUTC])
+
   const onChangeInternal = useCallback(
     (event: DateTimePickerEvent, date: Date | undefined) => {
       setShow(false)
@@ -64,7 +74,7 @@ export function DateInput(props: Props) {
             <Text
               type={props.buttonLabelType}
               style={[pal.text, props.buttonLabelStyle]}>
-              {props.value.toLocaleDateString()}
+              {formatter.format(props.value)}
             </Text>
           </View>
         </Button>
@@ -73,6 +83,7 @@ export function DateInput(props: Props) {
         <DateTimePicker
           testID={props.testID ? `${props.testID}-datepicker` : undefined}
           mode="date"
+          timeZoneName={props.handleAsUTC ? 'Etc/UTC' : undefined}
           display="spinner"
           // @ts-ignore applies in iOS only -prf
           themeVariant={theme.colorScheme}