From 5db709cba6f65b5a9b87e9a409574536b805a4b7 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 5 Aug 2025 10:37:33 -0500 Subject: [PATCH] Clean up state, remove Portal edits --- src/components/Portal.tsx | 2 +- .../AnnouncementBadge.tsx | 38 ++++++++ .../AnnouncementDialog.tsx | 31 +----- .../PolicyUpdate20250801.tsx | 28 ++---- .../dialogs/BlockingAnnouncements/common.tsx | 94 ------------------- .../dialogs/BlockingAnnouncements/index.tsx | 24 ++--- .../useAnnouncementState.ts | 34 +++++++ 7 files changed, 91 insertions(+), 160 deletions(-) create mode 100644 src/components/dialogs/BlockingAnnouncements/AnnouncementBadge.tsx delete mode 100644 src/components/dialogs/BlockingAnnouncements/common.tsx create mode 100644 src/components/dialogs/BlockingAnnouncements/useAnnouncementState.ts diff --git a/src/components/Portal.tsx b/src/components/Portal.tsx index 71b208579d..4e03d6b089 100644 --- a/src/components/Portal.tsx +++ b/src/components/Portal.tsx @@ -73,7 +73,7 @@ export function createPortalGroup() { return null } - return {Provider, Outlet, Portal, Context} + return {Provider, Outlet, Portal} } const DefaultPortal = createPortalGroup() diff --git a/src/components/dialogs/BlockingAnnouncements/AnnouncementBadge.tsx b/src/components/dialogs/BlockingAnnouncements/AnnouncementBadge.tsx new file mode 100644 index 0000000000..255b177ba1 --- /dev/null +++ b/src/components/dialogs/BlockingAnnouncements/AnnouncementBadge.tsx @@ -0,0 +1,38 @@ +import {View} from 'react-native' +import {Trans} from '@lingui/macro' + +import {Logo} from '#/view/icons/Logo' +import {atoms as a, useTheme} from '#/alf' +import {Text} from '#/components/Typography' + +export function AnnouncementBadge() { + const t = useTheme() + return ( + + + + + Announcement + + + + ) +} diff --git a/src/components/dialogs/BlockingAnnouncements/AnnouncementDialog.tsx b/src/components/dialogs/BlockingAnnouncements/AnnouncementDialog.tsx index c0896e1190..e59a851de7 100644 --- a/src/components/dialogs/BlockingAnnouncements/AnnouncementDialog.tsx +++ b/src/components/dialogs/BlockingAnnouncements/AnnouncementDialog.tsx @@ -1,10 +1,4 @@ -import { - createContext, - type ReactNode, - useContext, - useMemo, - useState, -} from 'react' +import {type ReactNode} from 'react' import {ScrollView, View} from 'react-native' import { useSafeAreaFrame, @@ -21,29 +15,6 @@ import {LockScroll} from '#/components/LockScroll' const GUTTER = 24 -export const Context = createContext({ - close: () => {}, -}) - -export function useAnnouncementDialogContext() { - return useContext(Context) -} - -export function AnnouncementDialogOuter({children}: {children: ReactNode}) { - const [open, setOpen] = useState(true) - - const ctx = useMemo( - () => ({ - close() { - setOpen(false) - }, - }), - [setOpen], - ) - - return {open && children} -} - export function AnnouncementDialog({ children, label, diff --git a/src/components/dialogs/BlockingAnnouncements/PolicyUpdate20250801.tsx b/src/components/dialogs/BlockingAnnouncements/PolicyUpdate20250801.tsx index b28f39c70c..27b1f57989 100644 --- a/src/components/dialogs/BlockingAnnouncements/PolicyUpdate20250801.tsx +++ b/src/components/dialogs/BlockingAnnouncements/PolicyUpdate20250801.tsx @@ -4,37 +4,23 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {isAndroid} from '#/platform/detection' -import {Nux} from '#/state/queries/nuxs' +import {useA11y} from '#/state/a11y' import {atoms as a, useTheme} from '#/alf' import {Button, ButtonText} from '#/components/Button' -import { - AnnouncementBadge, - useAnnouncementState, -} from '#/components/dialogs/BlockingAnnouncements/common' +import {AnnouncementBadge} from '#/components/dialogs/BlockingAnnouncements/AnnouncementBadge' +import {AnnouncementDialog} from '#/components/dialogs/BlockingAnnouncements/AnnouncementDialog' +import {type AnnouncementState} from '#/components/dialogs/BlockingAnnouncements/useAnnouncementState' import {InlineLinkText, Link} from '#/components/Link' import {Text} from '#/components/Typography' -import { - AnnouncementDialog, - useAnnouncementDialogContext, -} from '#/components/dialogs/BlockingAnnouncements/AnnouncementDialog' -import {useA11y} from '#/state/a11y' -export function useLocalState() { - return useAnnouncementState({ - id: Nux.BlockingAnnouncementPolicyUpdate20250801, - }) -} - -export function Announcement() { +export function Announcement({state}: {state: AnnouncementState}) { const t = useTheme() const {_} = useLingui() - const {complete} = useLocalState() - const {close} = useAnnouncementDialogContext() const {screenReaderEnabled} = useA11y() const handleClose = useCallback(() => { - close() - }, [close, complete]) + state.complete() + }, [state]) const linkStyle = [a.text_md] const links = { diff --git a/src/components/dialogs/BlockingAnnouncements/common.tsx b/src/components/dialogs/BlockingAnnouncements/common.tsx deleted file mode 100644 index cceaf49241..0000000000 --- a/src/components/dialogs/BlockingAnnouncements/common.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import {type ReactNode, useCallback, useMemo} from 'react' -import {View} from 'react-native' -import {Trans} from '@lingui/macro' - -import {type Nux, useNux, useSaveNux} from '#/state/queries/nuxs' -import {Logo} from '#/view/icons/Logo' -import {atoms as a, useTheme} from '#/alf' -import * as Dialog from '#/components/Dialog' -import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' -import {Text} from '#/components/Typography' - -export function useForceClose() { - const {close} = Dialog.useDialogContext() - return useCallback( - (cb?: () => void) => { - close(cb, true) - }, - [close], - ) -} - -export function useAnnouncementState({id}: {id: Nux}) { - const nux = useNux(id) - const {mutate: save, variables} = useSaveNux() - const optimisticallyCompleted = !!variables?.completed - return useMemo( - () => ({ - /** - * Until data has loaded, assumed completed - */ - completed: - optimisticallyCompleted || nux.status === 'ready' - ? nux.nux?.completed === true - : true, - complete() { - save({ - id, - completed: true, - data: undefined, - }) - }, - }), - [id, nux, save, optimisticallyCompleted], - ) -} - -export function BlockingAnnouncementDialogOuter({ - children, -}: { - children: ReactNode -}) { - const {signinDialogControl: control} = useGlobalDialogsControlContext() - - Dialog.useAutoOpen(control, 1e3) - - return ( - - - {children} - - ) -} - -export function AnnouncementBadge() { - const t = useTheme() - return ( - - - - - Announcement - - - - ) -} diff --git a/src/components/dialogs/BlockingAnnouncements/index.tsx b/src/components/dialogs/BlockingAnnouncements/index.tsx index b4f79223db..ae756ac96b 100644 --- a/src/components/dialogs/BlockingAnnouncements/index.tsx +++ b/src/components/dialogs/BlockingAnnouncements/index.tsx @@ -1,38 +1,34 @@ -import {useContext} from 'react' import {View} from 'react-native' +import {Nux} from '#/state/queries/nuxs' import {atoms as a} from '#/alf' -import {AnnouncementDialogOuter} from '#/components/dialogs/BlockingAnnouncements/AnnouncementDialog' import * as PolicyUpdate20250801 from '#/components/dialogs/BlockingAnnouncements/PolicyUpdate20250801' +import {useAnnouncementState} from '#/components/dialogs/BlockingAnnouncements/useAnnouncementState' import {createPortalGroup} from '#/components/Portal' const portalGroup = createPortalGroup() export const Provider = portalGroup.Provider export const Portal = portalGroup.Portal - -export function Outlet() { - const {outlet} = useContext(portalGroup.Context) - return outlet ? ( - {outlet} - ) : null -} +export const Outlet = portalGroup.Outlet export function BlockingAnnouncements() { - const policyUpdate20250801 = PolicyUpdate20250801.useLocalState() + const state = useAnnouncementState({ + id: Nux.BlockingAnnouncementPolicyUpdate20250801, + }) /* * See `window.clearNux` example in `/state/queries/nuxs` for a way to clear * NUX state for local testing and debugging. */ - if (policyUpdate20250801.completed) return null + if (state.completed) return null return ( - - - + + + ) } diff --git a/src/components/dialogs/BlockingAnnouncements/useAnnouncementState.ts b/src/components/dialogs/BlockingAnnouncements/useAnnouncementState.ts new file mode 100644 index 0000000000..47fecf7ed0 --- /dev/null +++ b/src/components/dialogs/BlockingAnnouncements/useAnnouncementState.ts @@ -0,0 +1,34 @@ +import {useMemo} from 'react' + +import {type Nux, useNux, useSaveNux} from '#/state/queries/nuxs' + +export type AnnouncementState = { + completed: boolean + complete: () => void +} + +export function useAnnouncementState({id}: {id: Nux}) { + const nux = useNux(id) + const {mutate: save, variables} = useSaveNux() + return useMemo(() => { + /** + * Until data has loaded, assumed completed + */ + let completed = nux.status === 'ready' ? nux.nux?.completed === true : true + + if (variables?.completed) { + completed = true + } + + return { + completed, + complete() { + save({ + id, + completed: true, + data: undefined, + }) + }, + } + }, [id, nux, save, variables]) +}