diff options
author | Samuel Newman <mozzius@protonmail.com> | 2024-03-15 15:45:58 +0000 |
---|---|---|
committer | Samuel Newman <mozzius@protonmail.com> | 2024-03-15 15:45:58 +0000 |
commit | 577091d44d15680d0c14f7d4571d630bf558a74d (patch) | |
tree | 74fea5ba491ce0d46b09b85727ce1ecb2c18ae86 /src | |
parent | 4f8381678da505737a96b7420c0f1ea8329f3672 (diff) | |
download | voidsky-577091d44d15680d0c14f7d4571d630bf558a74d.tar.zst |
ALF the birthday modal and remove legacy one
Diffstat (limited to 'src')
-rw-r--r-- | src/components/dialogs/BirthdaySettings.tsx | 122 | ||||
-rw-r--r-- | src/state/modals/index.tsx | 5 | ||||
-rw-r--r-- | src/view/com/modals/ContentFilteringSettings.tsx | 12 | ||||
-rw-r--r-- | src/view/com/modals/Modal.tsx | 4 | ||||
-rw-r--r-- | src/view/com/modals/Modal.web.tsx | 3 | ||||
-rw-r--r-- | src/view/screens/Settings/index.tsx | 18 |
6 files changed, 147 insertions, 17 deletions
diff --git a/src/components/dialogs/BirthdaySettings.tsx b/src/components/dialogs/BirthdaySettings.tsx new file mode 100644 index 000000000..00f6ff57e --- /dev/null +++ b/src/components/dialogs/BirthdaySettings.tsx @@ -0,0 +1,122 @@ +import React from 'react' +import {useLingui} from '@lingui/react' +import {Trans, msg} from '@lingui/macro' + +import * as Dialog from '#/components/Dialog' +import {Text} from '../Typography' +import {DateInput} from '#/view/com/util/forms/DateInput' +import {logger} from '#/logger' +import { + usePreferencesSetBirthDateMutation, + UsePreferencesQueryResponse, +} from '#/state/queries/preferences' +import {Button, ButtonText} from '../Button' +import {atoms as a, useBreakpoints, useTheme} from '#/alf' +import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' +import {cleanError} from '#/lib/strings/errors' +import {ActivityIndicator, View} from 'react-native' + +export function BirthdaySettingsDialog({ + control, + preferences, +}: { + control: Dialog.DialogControlProps + preferences: UsePreferencesQueryResponse | undefined +}) { + const {_} = useLingui() + const {isPending, isError, error, mutateAsync} = + usePreferencesSetBirthDateMutation() + + return ( + <Dialog.Outer control={control}> + <Dialog.Handle /> + <Dialog.Inner label={_(msg`My Birthday`)}> + {preferences && !isPending ? ( + <BirthdayInner + control={control} + preferences={preferences} + isError={isError} + error={error} + setBirthDate={mutateAsync} + /> + ) : ( + <ActivityIndicator size="large" style={a.my_5xl} /> + )} + </Dialog.Inner> + </Dialog.Outer> + ) +} + +function BirthdayInner({ + control, + preferences, + isError, + error, + setBirthDate, +}: { + control: Dialog.DialogControlProps + preferences: UsePreferencesQueryResponse + isError: boolean + error: unknown + setBirthDate: (args: {birthDate: Date}) => Promise<unknown> +}) { + const {_} = useLingui() + const [date, setDate] = React.useState(preferences.birthDate || new Date()) + const t = useTheme() + const {gtMobile} = useBreakpoints() + + const hasChanged = date !== preferences.birthDate + + const onSave = React.useCallback(async () => { + try { + // skip if date is the same + if (hasChanged) { + await setBirthDate({birthDate: date}) + } + control.close() + } catch (e) { + logger.error(`setBirthDate failed`, {message: e}) + } + }, [date, setBirthDate, control, hasChanged]) + + return ( + <View style={a.gap_lg}> + <View style={[a.gap_sm]}> + <Text style={[a.text_2xl, a.font_bold]}> + <Trans>My Birthday</Trans> + </Text> + <Text style={t.atoms.text_contrast_medium}> + <Trans>This information is not shared with other users.</Trans> + </Text> + </View> + <DateInput + handleAsUTC + testID="birthdayInput" + value={date} + onChange={setDate} + buttonType="default-light" + buttonStyle={[a.rounded_sm]} + buttonLabelType="lg" + accessibilityLabel={_(msg`Birthday`)} + accessibilityHint={_(msg`Enter your birth date`)} + accessibilityLabelledBy="birthDate" + /> + {isError ? ( + <ErrorMessage message={cleanError(error)} style={[a.rounded_sm]} /> + ) : undefined} + + <View style={gtMobile && [a.flex_row, a.justify_end]}> + <Button + label={hasChanged ? _(msg`Save birthday`) : _(msg`Done`)} + size={gtMobile ? 'small' : 'medium'} + onPress={onSave} + variant="solid" + color="primary"> + <ButtonText> + {hasChanged ? <Trans>Save</Trans> : <Trans>Done</Trans>} + </ButtonText> + </Button> + </View> + </View> + ) +} diff --git a/src/state/modals/index.tsx b/src/state/modals/index.tsx index a18f6c87c..db5be0b8d 100644 --- a/src/state/modals/index.tsx +++ b/src/state/modals/index.tsx @@ -135,10 +135,6 @@ export interface PostLanguagesSettingsModal { name: 'post-languages-settings' } -export interface BirthDateSettingsModal { - name: 'birth-date-settings' -} - export interface VerifyEmailModal { name: 'verify-email' showReminder?: boolean @@ -179,7 +175,6 @@ export type Modal = | ChangeHandleModal | DeleteAccountModal | EditProfileModal - | BirthDateSettingsModal | VerifyEmailModal | ChangeEmailModal | ChangePasswordModal diff --git a/src/view/com/modals/ContentFilteringSettings.tsx b/src/view/com/modals/ContentFilteringSettings.tsx index 328d23dc2..56bb9c837 100644 --- a/src/view/com/modals/ContentFilteringSettings.tsx +++ b/src/view/com/modals/ContentFilteringSettings.tsx @@ -24,6 +24,8 @@ import { CONFIGURABLE_LABEL_GROUPS, UsePreferencesQueryResponse, } from '#/state/queries/preferences' +import {useDialogControl} from '#/components/Dialog' +import {BirthdaySettingsDialog} from '#/components/dialogs/BirthdaySettings' export const snapPoints = ['90%'] @@ -107,11 +109,11 @@ function AdultContentEnabledPref() { const {_} = useLingui() const {data: preferences} = usePreferencesQuery() const {mutate, variables} = usePreferencesSetAdultContentMutation() - const {openModal} = useModalControls() + const bithdayDialogControl = useDialogControl() const onSetAge = React.useCallback( - () => openModal({name: 'birth-date-settings'}), - [openModal], + () => bithdayDialogControl.open(), + [bithdayDialogControl], ) const onToggleAdultContent = React.useCallback(async () => { @@ -135,6 +137,10 @@ function AdultContentEnabledPref() { return ( <View style={s.mb10}> + <BirthdaySettingsDialog + control={bithdayDialogControl} + preferences={preferences} + /> {isIOS ? ( preferences?.adultContentEnabled ? null : ( <Text type="md" style={pal.textLight}> diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx index e03879c1d..e382e6fab 100644 --- a/src/view/com/modals/Modal.tsx +++ b/src/view/com/modals/Modal.tsx @@ -25,7 +25,6 @@ import * as ContentFilteringSettingsModal from './ContentFilteringSettings' import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings' import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings' import * as ModerationDetailsModal from './ModerationDetails' -import * as BirthDateSettingsModal from './BirthDateSettings' import * as VerifyEmailModal from './VerifyEmail' import * as ChangeEmailModal from './ChangeEmail' import * as ChangePasswordModal from './ChangePassword' @@ -122,9 +121,6 @@ export function ModalsContainer() { } else if (activeModal?.name === 'moderation-details') { snapPoints = ModerationDetailsModal.snapPoints element = <ModerationDetailsModal.Component {...activeModal} /> - } else if (activeModal?.name === 'birth-date-settings') { - snapPoints = BirthDateSettingsModal.snapPoints - element = <BirthDateSettingsModal.Component /> } else if (activeModal?.name === 'verify-email') { snapPoints = VerifyEmailModal.snapPoints element = <VerifyEmailModal.Component {...activeModal} /> diff --git a/src/view/com/modals/Modal.web.tsx b/src/view/com/modals/Modal.web.tsx index d72b7e485..66ea2311f 100644 --- a/src/view/com/modals/Modal.web.tsx +++ b/src/view/com/modals/Modal.web.tsx @@ -27,7 +27,6 @@ import * as ContentFilteringSettingsModal from './ContentFilteringSettings' import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings' import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings' import * as ModerationDetailsModal from './ModerationDetails' -import * as BirthDateSettingsModal from './BirthDateSettings' import * as VerifyEmailModal from './VerifyEmail' import * as ChangeEmailModal from './ChangeEmail' import * as ChangePasswordModal from './ChangePassword' @@ -117,8 +116,6 @@ function Modal({modal}: {modal: ModalIface}) { element = <EditImageModal.Component {...modal} /> } else if (modal.name === 'moderation-details') { element = <ModerationDetailsModal.Component {...modal} /> - } else if (modal.name === 'birth-date-settings') { - element = <BirthDateSettingsModal.Component /> } else if (modal.name === 'verify-email') { element = <VerifyEmailModal.Component {...modal} /> } else if (modal.name === 'change-email') { diff --git a/src/view/screens/Settings/index.tsx b/src/view/screens/Settings/index.tsx index 00b507a99..4ea2a6701 100644 --- a/src/view/screens/Settings/index.tsx +++ b/src/view/screens/Settings/index.tsx @@ -40,7 +40,10 @@ import { } from '#/state/preferences' import {useSession, useSessionApi, SessionAccount} from '#/state/session' import {useProfileQuery} from '#/state/queries/profile' -import {useClearPreferencesMutation} from '#/state/queries/preferences' +import { + useClearPreferencesMutation, + usePreferencesQuery, +} from '#/state/queries/preferences' // TODO import {useInviteCodesQuery} from '#/state/queries/invites' import {clear as clearStorage} from '#/state/persisted/store' import {clearLegacyStorage} from '#/state/persisted/legacy' @@ -68,6 +71,7 @@ import {SelectableBtn} from 'view/com/util/forms/SelectableBtn' import {AccountDropdownBtn} from 'view/com/util/AccountDropdownBtn' import {SimpleViewHeader} from 'view/com/util/SimpleViewHeader' import {ExportCarDialog} from './ExportCarDialog' +import {BirthdaySettingsDialog} from '#/components/dialogs/BirthdaySettings' function SettingsAccountCard({account}: {account: SessionAccount}) { const pal = usePalette('default') @@ -152,6 +156,7 @@ export function SettingsScreen({}: Props) { const {screen, track} = useAnalytics() const {openModal} = useModalControls() const {isSwitchingAccounts, accounts, currentAccount} = useSession() + const {data: preferences} = usePreferencesQuery() const {mutate: clearPreferences} = useClearPreferencesMutation() // TODO // const {data: invites} = useInviteCodesQuery() @@ -159,6 +164,7 @@ export function SettingsScreen({}: Props) { const {setShowLoggedOut} = useLoggedOutViewControls() const closeAllActiveElements = useCloseAllActiveElements() const exportCarControl = useDialogControl() + const birthdayControl = useDialogControl() // const primaryBg = useCustomPalette<ViewStyle>({ // light: {backgroundColor: colors.blue0}, @@ -269,6 +275,10 @@ export function SettingsScreen({}: Props) { Linking.openURL(STATUS_PAGE_URL) }, []) + const onPressBirthday = React.useCallback(() => { + birthdayControl.open() + }, [birthdayControl]) + const clearAllStorage = React.useCallback(async () => { await clearStorage() Toast.show(_(msg`Storage cleared, you need to restart the app now.`)) @@ -281,6 +291,10 @@ export function SettingsScreen({}: Props) { return ( <View style={s.hContentRegion} testID="settingsScreen"> <ExportCarDialog control={exportCarControl} /> + <BirthdaySettingsDialog + control={birthdayControl} + preferences={preferences} + /> <SimpleViewHeader showBackButton={isMobile} @@ -339,7 +353,7 @@ export function SettingsScreen({}: Props) { <Text type="lg-medium" style={pal.text}> <Trans>Birthday:</Trans>{' '} </Text> - <Link onPress={() => openModal({name: 'birth-date-settings'})}> + <Link onPress={onPressBirthday}> <Text type="lg" style={pal.link}> <Trans>Show</Trans> </Text> |