From f86844eacab07f7b9795da4fb1603dca491d4b6a Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 18 Sep 2024 14:05:38 -0500 Subject: [PATCH] Add neue type nux --- src/components/Dialog/index.tsx | 1 + src/components/Dialog/index.web.tsx | 1 + src/components/Dialog/utils.ts | 18 +++ .../dialogs/nuxs/NeueTypography.tsx | 119 ++++++++++++++++++ src/components/dialogs/nuxs/index.tsx | 75 +++++++++-- src/state/queries/nuxs/definitions.ts | 15 ++- 6 files changed, 217 insertions(+), 12 deletions(-) create mode 100644 src/components/Dialog/utils.ts create mode 100644 src/components/dialogs/nuxs/NeueTypography.tsx diff --git a/src/components/Dialog/index.tsx b/src/components/Dialog/index.tsx index cdce3765f0..d5d92048ad 100644 --- a/src/components/Dialog/index.tsx +++ b/src/components/Dialog/index.tsx @@ -37,6 +37,7 @@ import {Portal} from '#/components/Portal' export {useDialogContext, useDialogControl} from '#/components/Dialog/context' export * from '#/components/Dialog/types' +export * from '#/components/Dialog/utils' // @ts-ignore export const Input = createInput(BottomSheetTextInput) diff --git a/src/components/Dialog/index.web.tsx b/src/components/Dialog/index.web.tsx index aff1842f77..bf20bd2956 100644 --- a/src/components/Dialog/index.web.tsx +++ b/src/components/Dialog/index.web.tsx @@ -27,6 +27,7 @@ import {Portal} from '#/components/Portal' export {useDialogContext, useDialogControl} from '#/components/Dialog/context' export * from '#/components/Dialog/types' +export * from '#/components/Dialog/utils' export {Input} from '#/components/forms/TextField' const stopPropagation = (e: any) => e.stopPropagation() diff --git a/src/components/Dialog/utils.ts b/src/components/Dialog/utils.ts new file mode 100644 index 0000000000..058d6e8041 --- /dev/null +++ b/src/components/Dialog/utils.ts @@ -0,0 +1,18 @@ +import React from 'react' + +import {DialogControlProps} from '#/components/Dialog/types' + +export function useAutoOpen(control: DialogControlProps, showTimeout?: number) { + React.useEffect(() => { + if (showTimeout) { + const timeout = setTimeout(() => { + control.open() + }, showTimeout) + return () => { + clearTimeout(timeout) + } + } else { + control.open() + } + }, [control, showTimeout]) +} diff --git a/src/components/dialogs/nuxs/NeueTypography.tsx b/src/components/dialogs/nuxs/NeueTypography.tsx new file mode 100644 index 0000000000..f33cea8e78 --- /dev/null +++ b/src/components/dialogs/nuxs/NeueTypography.tsx @@ -0,0 +1,119 @@ +import React from 'react' +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {AppearanceToggleButtonGroup} from '#/screens/Settings/AppearanceSettings' +import {atoms as a, useAlf, useTheme} from '#/alf' +import * as Dialog from '#/components/Dialog' +import {useNuxDialogContext} from '#/components/dialogs/nuxs' +import {Divider} from '#/components/Divider' +import {TextSize_Stroke2_Corner0_Rounded as TextSize} from '#/components/icons/TextSize' +import {TitleCase_Stroke2_Corner0_Rounded as Aa} from '#/components/icons/TitleCase' +import {Text} from '#/components/Typography' + +export function NeueTypography() { + const t = useTheme() + const {_} = useLingui() + const nuxDialogs = useNuxDialogContext() + const control = Dialog.useDialogControl() + const {fonts} = useAlf() + + Dialog.useAutoOpen(control, 3e3) + + const onClose = React.useCallback(() => { + nuxDialogs.dismissActiveNux() + }, [nuxDialogs]) + + const onChangeFontFamily = React.useCallback( + (values: string[]) => { + const next = values[0] === 'system' ? 'system' : 'theme' + fonts.setFontFamily(next) + }, + [fonts], + ) + + const onChangeFontScale = React.useCallback( + (values: string[]) => { + const next = values[0] || ('0' as any) + fonts.setFontScale(next) + }, + [fonts], + ) + + return ( + + + + + + + + Introducing new font settings ✨ + + + + To the ensure the best possible experience, we're introducing a + new theme font, along with adjustable font sizing settings. + + + + + Defaults are shown below. You can edit these in your Appearance + Settings later. + + + + + + + + + + + + + + + + + ) +} diff --git a/src/components/dialogs/nuxs/index.tsx b/src/components/dialogs/nuxs/index.tsx index a38c87b68e..e826895cba 100644 --- a/src/components/dialogs/nuxs/index.tsx +++ b/src/components/dialogs/nuxs/index.tsx @@ -1,4 +1,5 @@ import React from 'react' +import {AppBskyActorDefs} from '@atproto/api' import {useGate} from '#/lib/statsig/statsig' import {logger} from '#/logger' @@ -8,9 +9,16 @@ import { useRemoveNuxsMutation, useUpsertNuxMutation, } from '#/state/queries/nuxs' -import {useSession} from '#/state/session' +import { + usePreferencesQuery, + UsePreferencesQueryResponse, +} from '#/state/queries/preferences' +import {useProfileQuery} from '#/state/queries/profile' +import {SessionAccount, useSession} from '#/state/session' import {useOnboardingState} from '#/state/shell' +import {NeueTypography} from '#/components/dialogs/nuxs/NeueTypography' import {isSnoozed, snooze, unsnooze} from '#/components/dialogs/nuxs/snoozing' +// NUXs import {TenMillion} from '#/components/dialogs/nuxs/TenMillion' import {IS_DEV} from '#/env' @@ -21,11 +29,27 @@ type Context = { const queuedNuxs: { id: Nux - enabled?: (props: {gate: ReturnType}) => boolean + enabled?: (props: { + gate: ReturnType + currentAccount: SessionAccount + currentProfile: AppBskyActorDefs.ProfileViewDetailed + preferences: UsePreferencesQueryResponse + }) => boolean }[] = [ { id: Nux.TenMillionDialog, }, + { + id: Nux.NeueTypography, + enabled(props) { + if (props.currentProfile.createdAt) { + if (new Date(props.currentProfile.createdAt) < new Date('2024-09-25')) { + return true + } + } + return false + }, + }, ] const Context = React.createContext({ @@ -38,12 +62,31 @@ export function useNuxDialogContext() { } export function NuxDialogs() { - const {hasSession} = useSession() - const onboardingState = useOnboardingState() - return hasSession && !onboardingState.isActive ? : null + const {currentAccount} = useSession() + const {data: preferences} = usePreferencesQuery() + const {data: profile} = useProfileQuery({did: currentAccount?.did}) + const onboardingActive = useOnboardingState().isActive + + const isLoading = + !currentAccount || !preferences || !profile || onboardingActive + return isLoading ? null : ( + + ) } -function Inner() { +function Inner({ + currentAccount, + currentProfile, + preferences, +}: { + currentAccount: SessionAccount + currentProfile: AppBskyActorDefs.ProfileViewDetailed + preferences: UsePreferencesQueryResponse +}) { const gate = useGate() const {nuxs} = useNuxs() const [snoozed, setSnoozed] = React.useState(() => { @@ -83,7 +126,13 @@ function Inner() { if (nux && nux.completed) continue // then check gate (track exposure) - if (enabled && !enabled({gate})) continue + if ( + enabled && + !enabled({gate, currentAccount, currentProfile, preferences}) + ) + continue + + logger.debug(`NUX dialogs: activating '${id}' NUX`) // we have a winner setActiveNux(id) @@ -104,7 +153,16 @@ function Inner() { break } - }, [nuxs, snoozed, snoozeNuxDialog, upsertNux, gate]) + }, [ + nuxs, + snoozed, + snoozeNuxDialog, + upsertNux, + gate, + currentAccount, + currentProfile, + preferences, + ]) const ctx = React.useMemo(() => { return { @@ -116,6 +174,7 @@ function Inner() { return ( {activeNux === Nux.TenMillionDialog && } + {activeNux === Nux.NeueTypography && } ) } diff --git a/src/state/queries/nuxs/definitions.ts b/src/state/queries/nuxs/definitions.ts index 865967d37a..63a8079623 100644 --- a/src/state/queries/nuxs/definitions.ts +++ b/src/state/queries/nuxs/definitions.ts @@ -4,15 +4,22 @@ import {BaseNux} from '#/state/queries/nuxs/types' export enum Nux { TenMillionDialog = 'TenMillionDialog', + NeueTypography = 'NeueTypography', } export const nuxNames = new Set(Object.values(Nux)) -export type AppNux = BaseNux<{ - id: Nux.TenMillionDialog - data: undefined -}> +export type AppNux = + | BaseNux<{ + id: Nux.TenMillionDialog + data: undefined + }> + | BaseNux<{ + id: Nux.NeueTypography + data: undefined + }> export const NuxSchemas: Record | undefined> = { [Nux.TenMillionDialog]: undefined, + [Nux.NeueTypography]: undefined, }