From 1b5242c1d613fa19e9c86983d49a5d9fba797d47 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Wed, 17 Jun 2026 12:45:01 +0300 Subject: [PATCH] Rip out `Modal` system completely (#9903) --- package.json | 3 +- patches/@discord__bottom-sheet@4.6.1.patch | 13 --- pnpm-lock.yaml | 58 ---------- pnpm-workspace.yaml | 1 - src/App.native.tsx | 31 +++--- src/App.web.tsx | 21 ++-- src/components/Link.tsx | 5 - src/state/modals/index.tsx | 105 ------------------ src/state/util.ts | 17 +-- src/view/com/composer/Composer.tsx | 6 +- src/view/com/modals/Modal.tsx | 91 --------------- src/view/com/modals/Modal.web.tsx | 101 ----------------- src/view/com/modals/util.tsx | 4 - src/view/com/modals/util.web.tsx | 1 - .../com/util/BottomSheetCustomBackdrop.tsx | 48 -------- src/view/com/util/Link.tsx | 10 -- src/view/shell/Composer.web.tsx | 9 +- src/view/shell/index.tsx | 2 - src/view/shell/index.web.tsx | 2 - 19 files changed, 29 insertions(+), 499 deletions(-) delete mode 100644 patches/@discord__bottom-sheet@4.6.1.patch delete mode 100644 src/state/modals/index.tsx delete mode 100644 src/view/com/modals/Modal.tsx delete mode 100644 src/view/com/modals/Modal.web.tsx delete mode 100644 src/view/com/modals/util.tsx delete mode 100644 src/view/com/modals/util.web.tsx delete mode 100644 src/view/com/util/BottomSheetCustomBackdrop.tsx diff --git a/package.json b/package.json index a543300494..d6cd28c269 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,6 @@ "@bsky.app/sift": "^0.3.9", "@bsky.app/tapper": "^0.6.1", "@bsky.app/video": "0.3.6", - "@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet", "@emoji-mart/data": "^1.2.1", "@emoji-mart/react": "^1.1.1", "@expo/html-elements": "^0.12.5", @@ -332,7 +331,7 @@ "^await-lock$": "/node_modules/await-lock/build/AwaitLock.js" }, "transformIgnorePatterns": [ - "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|@discord|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|nanoid|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|normalize-url|react-native-svg|@sentry/.*|sentry-expo|bcp-47-match|@atproto/.*|multiformats|uint8arrays|@ipld/.*|cborg|await-lock)" + "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|nanoid|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|normalize-url|react-native-svg|@sentry/.*|sentry-expo|bcp-47-match|@atproto/.*|multiformats|uint8arrays|@ipld/.*|cborg|await-lock)" ], "modulePathIgnorePatterns": [ "__tests__/.*/__mocks__", diff --git a/patches/@discord__bottom-sheet@4.6.1.patch b/patches/@discord__bottom-sheet@4.6.1.patch deleted file mode 100644 index 133052e5d6..0000000000 --- a/patches/@discord__bottom-sheet@4.6.1.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/src/hooks/useStableCallback.ts b/src/hooks/useStableCallback.ts -index 1c788ab72351c21c5aea178d7b416741aa940e1f..d30f330ab1f082ea0477c19e2fa05b7a0b1a3e0d 100644 ---- a/src/hooks/useStableCallback.ts -+++ b/src/hooks/useStableCallback.ts -@@ -6,7 +6,7 @@ type Callback = (...args: any[]) => any; - * https://gist.github.com/JakeCoxon/c7ebf6e6496f8468226fd36b596e1985 - */ - export const useStableCallback = (callback: Callback) => { -- const callbackRef = useRef(); -+ const callbackRef = useRef(undefined); - const memoCallback = useCallback( - (...args: any) => callbackRef.current && callbackRef.current(...args), - [] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 80917f76c4..6353790b2e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -215,7 +215,6 @@ overrides: react-native-screens: 4.24.0 patchedDependencies: - '@discord/bottom-sheet@4.6.1': 253965341bfbc8e63630dfca511c5d0e0878900e5fe414b2278bd322fc215e2a '@sentry/react-native@6.20.0': 1d48e4d5178f5684eb33262299e7eed283bf9601f79b9ae1af63a7f607d3483a expo-glass-effect@55.0.8: 6c9fa5b104e53b87df4e17b320acb3b94d12ac90c0101190045dd620681efff0 expo-haptics@15.0.8: b33910ba2753c4eccdc885b449e6e33aa90b9cefa75ca8639762a26013141410 @@ -286,9 +285,6 @@ importers: '@bsky.app/video': specifier: 0.3.6 version: 0.3.6(expo@54.0.34(@babel/core@7.29.0)(react-native-webview@13.15.0(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) - '@discord/bottom-sheet': - specifier: bluesky-social/react-native-bottom-sheet - version: https://codeload.github.com/bluesky-social/react-native-bottom-sheet/tar.gz/28a87d1bb55e10fc355fa1455545a30734995908(patch_hash=253965341bfbc8e63630dfca511c5d0e0878900e5fe414b2278bd322fc215e2a)(@shopify/flash-list@2.3.1(@babel/runtime@7.29.2)(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(@types/react@19.1.17)(react-native-gesture-handler@2.28.0(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-reanimated@3.19.1(patch_hash=97a1967f37a4213fbab59e1fd59a1bf859b5efc79af5e1b528a47fe488e6c5d6)(@babel/core@7.29.0)(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) '@emoji-mart/data': specifier: ^1.2.1 version: 1.2.1 @@ -1699,23 +1695,6 @@ packages: resolution: {integrity: sha512-JRrHvitc0w+r/h6XXSOq917HxsjRoxPEtyNYSmylKirjiPNrRx84VKtqFlOIWIFCOZI5BoXg6hNpE0Zq7CwVBA==} hasBin: true - '@discord/bottom-sheet@https://codeload.github.com/bluesky-social/react-native-bottom-sheet/tar.gz/28a87d1bb55e10fc355fa1455545a30734995908': - resolution: {gitHosted: true, integrity: sha512-zsoB8sFUx8O9aO0fKAkzoWLMyaX7EBd3ooNYjzsh9vr/c9zg/a3jOAbWzWbvM86QCZIszfbW9GXeJZKZRVk/tg==, tarball: https://codeload.github.com/bluesky-social/react-native-bottom-sheet/tar.gz/28a87d1bb55e10fc355fa1455545a30734995908} - version: 4.6.1 - peerDependencies: - '@shopify/flash-list': '*' - '@types/react': '*' - '@types/react-native': '*' - react: '*' - react-native: '*' - react-native-gesture-handler: '>=1.10.1' - react-native-reanimated: 3.19.1 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-native': - optional: true - '@discoveryjs/json-ext@0.5.7': resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} engines: {node: '>=10.0.0'} @@ -2107,12 +2086,6 @@ packages: '@formatjs/intl-supportedvaluesof@2.3.7': resolution: {integrity: sha512-ZTXEKijV5H08z19odngZPsXlmGndfukHuVnjd9qyER77XSk/yJwDMiSjoJYY5C5WxFs2UN4s/EMtu75e6Tp3ug==} - '@gorhom/portal@1.0.14': - resolution: {integrity: sha512-MXyL4xvCjmgaORr/rtryDNFy3kU4qUbKlwtQqqsygd0xX3mhKjOLn6mQK8wfu0RkoE0pBE0nAasRoHua+/QZ7A==} - peerDependencies: - react: '*' - react-native: '*' - '@growthbook/growthbook-react@1.6.5': resolution: {integrity: sha512-afi/RUbwazVNKv2acn6wDQz4BJNRAEpwIuHfggQup2/aE5PLAxy3+95gjjRMgCcPR0Pf3sFmhYGvOmxLD0ZRbQ==} engines: {node: '>=10'} @@ -3367,13 +3340,6 @@ packages: peerDependencies: webpack: '>=4.40.0' - '@shopify/flash-list@2.3.1': - resolution: {integrity: sha512-7oktg2NQR7KAODjFoDaWe8/OBzyYbdTE3zQTrUBMxjIbxHTHN7UXRX1hX3DHk8KvtkgQdRfZOV8Gjj2l4fGrXw==} - peerDependencies: - '@babel/runtime': '*' - react: '*' - react-native: '*' - '@sinclair/typebox@0.27.10': resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} @@ -10521,18 +10487,6 @@ snapshots: transitivePeerDependencies: - encoding - ? '@discord/bottom-sheet@https://codeload.github.com/bluesky-social/react-native-bottom-sheet/tar.gz/28a87d1bb55e10fc355fa1455545a30734995908(patch_hash=253965341bfbc8e63630dfca511c5d0e0878900e5fe414b2278bd322fc215e2a)(@shopify/flash-list@2.3.1(@babel/runtime@7.29.2)(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(@types/react@19.1.17)(react-native-gesture-handler@2.28.0(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-reanimated@3.19.1(patch_hash=97a1967f37a4213fbab59e1fd59a1bf859b5efc79af5e1b528a47fe488e6c5d6)(@babel/core@7.29.0)(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)' - : dependencies: - '@gorhom/portal': 1.0.14(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) - '@shopify/flash-list': 2.3.1(@babel/runtime@7.29.2)(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) - invariant: 2.2.4 - react: 19.1.0 - react-native: 0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0) - react-native-gesture-handler: 2.28.0(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) - react-native-reanimated: 3.19.1(patch_hash=97a1967f37a4213fbab59e1fd59a1bf859b5efc79af5e1b528a47fe488e6c5d6)(@babel/core@7.29.0)(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) - optionalDependencies: - '@types/react': 19.1.17 - '@discoveryjs/json-ext@0.5.7': {} '@egjs/hammerjs@2.0.17': @@ -11103,12 +11057,6 @@ snapshots: dependencies: '@formatjs/fast-memoize': 3.1.5 - '@gorhom/portal@1.0.14(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)': - dependencies: - nanoid: 3.3.12 - react: 19.1.0 - react-native: 0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0) - '@growthbook/growthbook-react@1.6.5(react@19.1.0)': dependencies: '@growthbook/growthbook': 1.6.5 @@ -12616,12 +12564,6 @@ snapshots: - encoding - supports-color - '@shopify/flash-list@2.3.1(@babel/runtime@7.29.2)(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)': - dependencies: - '@babel/runtime': 7.29.2 - react: 19.1.0 - react-native: 0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0) - '@sinclair/typebox@0.27.10': {} '@sinclair/typebox@0.34.49': {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e9fd14022d..182228486d 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -19,7 +19,6 @@ allowBuilds: 'esbuild': true 'unrs-resolver': true patchedDependencies: - '@discord/bottom-sheet@4.6.1': patches/@discord__bottom-sheet@4.6.1.patch '@sentry/react-native@6.20.0': patches/@sentry__react-native@6.20.0.patch 'expo-glass-effect@55.0.8': patches/expo-glass-effect@55.0.8.patch 'expo-haptics@15.0.8': patches/expo-haptics@15.0.8.patch diff --git a/src/App.native.tsx b/src/App.native.tsx index 22dd39f9d7..d41f28bdb5 100644 --- a/src/App.native.tsx +++ b/src/App.native.tsx @@ -31,7 +31,6 @@ import {listenSessionDropped} from '#/state/events' import {GlobalGestureEventsProvider} from '#/state/global-gesture-events' import {Provider as HomeBadgeProvider} from '#/state/home-badge' import {MessagesProvider} from '#/state/messages' -import {Provider as ModalStateProvider} from '#/state/modals' import {init as initPersistedState} from '#/state/persisted' import {Provider as PrefsStateProvider} from '#/state/preferences' import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs' @@ -241,22 +240,20 @@ function App() { - - - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/src/App.web.tsx b/src/App.web.tsx index 6faf6f2218..e962728859 100644 --- a/src/App.web.tsx +++ b/src/App.web.tsx @@ -24,7 +24,6 @@ import {Provider as EmailVerificationProvider} from '#/state/email-verification' import {listenSessionDropped} from '#/state/events' import {Provider as HomeBadgeProvider} from '#/state/home-badge' import {MessagesProvider} from '#/state/messages' -import {Provider as ModalStateProvider} from '#/state/modals' import {init as initPersistedState} from '#/state/persisted' import {Provider as PrefsStateProvider} from '#/state/preferences' import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs' @@ -220,17 +219,15 @@ function App() { - - - - - - - - - - - + + + + + + + + + diff --git a/src/components/Link.tsx b/src/components/Link.tsx index 258ba58ca4..0818b2a26f 100644 --- a/src/components/Link.tsx +++ b/src/components/Link.tsx @@ -26,7 +26,6 @@ import { isExternalUrl, linkRequiresWarning, } from '#/lib/strings/url-helpers' -import {useModalControls} from '#/state/modals' import {useInAppBrowser} from '#/state/preferences/in-app-browser' import {atoms as a, flatten, type TextStyleProp, useTheme, web} from '#/alf' import {Button, type ButtonProps} from '#/components/Button' @@ -140,7 +139,6 @@ export function useLink({ } const isExternal = isExternalUrl(href) - const {closeModal} = useModalControls() const {linkWarningDialogControl} = useGlobalDialogsControlContext() const openLink = useOpenLink() const groupChatJoinIntent = useGroupChatJoinIntent() @@ -188,8 +186,6 @@ export function useLink({ ) { void openLink(href) } else { - closeModal() // close any active modals - const [screen, params] = router.matchPath(href) as [ screen: keyof AllNavigatorParams, params?: RouteParams, @@ -242,7 +238,6 @@ export function useLink({ isExternal, href, openLink, - closeModal, action, navigation, overridePresentation, diff --git a/src/state/modals/index.tsx b/src/state/modals/index.tsx deleted file mode 100644 index d62ba2a7a0..0000000000 --- a/src/state/modals/index.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import {createContext, useContext, useEffect, useMemo, useState} from 'react' - -import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' -import {useHotkeysContext} from '#/lib/hotkeys' - -export interface ContentLanguagesSettingsModal { - name: 'content-languages-settings' -} - -/** - * @deprecated DO NOT ADD NEW MODALS - */ -export type Modal = - // Curation - ContentLanguagesSettingsModal - -const ModalContext = createContext<{ - isModalActive: boolean - activeModals: Modal[] -}>({ - isModalActive: false, - activeModals: [], -}) -ModalContext.displayName = 'ModalContext' - -const ModalControlContext = createContext<{ - openModal: (modal: Modal) => void - closeModal: () => boolean - closeAllModals: () => boolean -}>({ - openModal: () => {}, - closeModal: () => false, - closeAllModals: () => false, -}) -ModalControlContext.displayName = 'ModalControlContext' - -export function Provider({children}: React.PropsWithChildren<{}>) { - const [activeModals, setActiveModals] = useState([]) - const {disableScope, enableScope} = useHotkeysContext() - - useEffect(() => { - if (activeModals.length > 0) { - disableScope('global') - } else { - enableScope('global') - } - }, [activeModals.length, disableScope, enableScope]) - - const openModal = useNonReactiveCallback((modal: Modal) => { - setActiveModals(modals => [...modals, modal]) - }) - - const closeModal = useNonReactiveCallback(() => { - let wasActive = activeModals.length > 0 - setActiveModals(modals => { - return modals.slice(0, -1) - }) - return wasActive - }) - - const closeAllModals = useNonReactiveCallback(() => { - let wasActive = activeModals.length > 0 - setActiveModals([]) - return wasActive - }) - - const state = useMemo( - () => ({ - isModalActive: activeModals.length > 0, - activeModals, - }), - [activeModals], - ) - - const methods = useMemo( - () => ({ - openModal, - closeModal, - closeAllModals, - }), - [openModal, closeModal, closeAllModals], - ) - - return ( - - - {children} - - - ) -} - -/** - * @deprecated use the dialog system from `#/components/Dialog.tsx` - */ -export function useModals() { - return useContext(ModalContext) -} - -/** - * @deprecated use the dialog system from `#/components/Dialog.tsx` - */ -export function useModalControls() { - return useContext(ModalControlContext) -} diff --git a/src/state/util.ts b/src/state/util.ts index 239aab5aca..7924b103cf 100644 --- a/src/state/util.ts +++ b/src/state/util.ts @@ -2,7 +2,6 @@ import {useCallback} from 'react' import {useDialogStateControlContext} from '#/state/dialogs' import {useLightboxControls} from '#/components/Lightbox/state' -import {useModalControls} from './modals' import {useComposerControls} from './shell/composer' import {useSetDrawerOpen} from './shell/drawer-open' @@ -12,7 +11,6 @@ import {useSetDrawerOpen} from './shell/drawer-open' */ export function useCloseAnyActiveElement() { const {closeLightbox} = useLightboxControls() - const {closeModal} = useModalControls() const {closeComposer} = useComposerControls() const {closeAllDialogs} = useDialogStateControlContext() const setDrawerOpen = useSetDrawerOpen() @@ -20,9 +18,6 @@ export function useCloseAnyActiveElement() { if (closeLightbox()) { return true } - if (closeModal()) { - return true - } if (closeAllDialogs()) { return true } @@ -31,7 +26,7 @@ export function useCloseAnyActiveElement() { } setDrawerOpen(false) return false - }, [closeLightbox, closeModal, closeComposer, setDrawerOpen, closeAllDialogs]) + }, [closeLightbox, closeComposer, setDrawerOpen, closeAllDialogs]) } /** @@ -39,21 +34,13 @@ export function useCloseAnyActiveElement() { */ export function useCloseAllActiveElements() { const {closeLightbox} = useLightboxControls() - const {closeAllModals} = useModalControls() const {closeComposer} = useComposerControls() const {closeAllDialogs: closeAlfDialogs} = useDialogStateControlContext() const setDrawerOpen = useSetDrawerOpen() return useCallback(() => { closeLightbox() - closeAllModals() closeComposer() closeAlfDialogs() setDrawerOpen(false) - }, [ - closeLightbox, - closeAllModals, - closeComposer, - closeAlfDialogs, - setDrawerOpen, - ]) + }, [closeLightbox, closeComposer, closeAlfDialogs, setDrawerOpen]) } diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 3ddaf41ed7..54932286be 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -86,7 +86,6 @@ import { createComposerImage, pasteImage, } from '#/state/gallery' -import {useModalControls} from '#/state/modals' import {useRequireAltTextEnabled} from '#/state/preferences' import { fromPostLanguages, @@ -283,7 +282,6 @@ export const ComposePost = ({ useSaveDraftMutation() const {mutate: cleanupPublishedDraft} = useCleanupPublishedDraftMutation() const {closeAllDialogs} = useDialogStateControlContext() - const {closeAllModals} = useModalControls() const {data: preferences} = usePreferencesQuery() const navigation = useNavigation() @@ -835,7 +833,7 @@ export const ComposePost = ({ const backHandler = BackHandler.addEventListener( 'hardwareBackPress', () => { - if (closeAllDialogs() || closeAllModals()) { + if (closeAllDialogs()) { return true } onPressCancel() @@ -845,7 +843,7 @@ export const ComposePost = ({ return () => { backHandler.remove() } - }, [onPressCancel, closeAllDialogs, closeAllModals]) + }, [onPressCancel, closeAllDialogs]) const missingAltError = useMemo(() => { if (!requireAltTextEnabled) { diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx deleted file mode 100644 index 96b04a1428..0000000000 --- a/src/view/com/modals/Modal.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import {Fragment, useEffect, useRef} from 'react' -import {StyleSheet} from 'react-native' -import {SafeAreaView} from 'react-native-safe-area-context' -import BottomSheet from '@discord/bottom-sheet/src' - -import {usePalette} from '#/lib/hooks/usePalette' -import {useModalControls, useModals} from '#/state/modals' -import {FullWindowOverlay} from '#/components/FullWindowOverlay' -import {createCustomBackdrop} from '../util/BottomSheetCustomBackdrop' - -const DEFAULT_SNAPPOINTS = ['90%'] -const HANDLE_HEIGHT = 24 - -export function ModalsContainer() { - const {isModalActive, activeModals} = useModals() - const {closeModal} = useModalControls() - const bottomSheetRef = useRef(null) - const pal = usePalette('default') - const activeModal = activeModals[activeModals.length - 1] - - const onBottomSheetChange = async (snapPoint: number) => { - if (snapPoint === -1) { - closeModal() - } - } - - const onClose = () => { - bottomSheetRef.current?.close() - closeModal() - } - - useEffect(() => { - if (isModalActive) { - bottomSheetRef.current?.snapToIndex(0) - } else { - bottomSheetRef.current?.close() - } - }, [isModalActive, bottomSheetRef, activeModal?.name]) - - let snapPoints: (string | number)[] = DEFAULT_SNAPPOINTS - let element - { - return null - } - - if (snapPoints[0] === 'fullscreen') { - return ( - - {element} - - ) - } - - const Container = activeModal ? FullWindowOverlay : Fragment - - return ( - - - {element} - - - ) -} - -const styles = StyleSheet.create({ - handle: { - borderTopLeftRadius: 10, - borderTopRightRadius: 10, - }, - fullscreenContainer: { - position: 'absolute', - top: 0, - left: 0, - bottom: 0, - right: 0, - }, -}) diff --git a/src/view/com/modals/Modal.web.tsx b/src/view/com/modals/Modal.web.tsx deleted file mode 100644 index a35c2b391b..0000000000 --- a/src/view/com/modals/Modal.web.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native' -import Animated, {FadeIn, FadeOut} from 'react-native-reanimated' -import {RemoveScrollBar} from 'react-remove-scroll-bar' - -import {usePalette} from '#/lib/hooks/usePalette' -import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' -import {type Modal as ModalIface} from '#/state/modals' -import {useModalControls, useModals} from '#/state/modals' - -export function ModalsContainer() { - const {isModalActive, activeModals} = useModals() - - if (!isModalActive) { - return null - } - - return ( - <> - - {activeModals.map((modal, i) => ( - - ))} - - ) -} - -function Modal({modal: _modal}: {modal: ModalIface}) { - const {isModalActive} = useModals() - const {closeModal} = useModalControls() - const pal = usePalette('default') - const {isMobile} = useWebMediaQueries() - - if (!isModalActive) { - return null - } - - const onPressMask = () => { - closeModal() - } - const onInnerPress = () => { - // TODO: can we use prevent default? - // do nothing, we just want to stop it from bubbling - } - - let element - { - return null - } - - return ( - // eslint-disable-next-line react-native-a11y/has-valid-accessibility-descriptors - - - {/* eslint-disable-next-line react-native-a11y/has-valid-accessibility-descriptors */} - - - {element} - - - - - ) -} - -const styles = StyleSheet.create({ - mask: { - // @ts-ignore - position: 'fixed', - top: 0, - left: 0, - width: '100%', - height: '100%', - backgroundColor: '#000c', - alignItems: 'center', - justifyContent: 'center', - }, - container: { - width: 600, - // @ts-ignore web only - maxWidth: '100vw', - // @ts-ignore web only - maxHeight: '90vh', - paddingVertical: 20, - paddingHorizontal: 24, - borderRadius: 8, - borderWidth: 1, - }, - containerMobile: { - borderRadius: 0, - paddingHorizontal: 0, - }, -}) diff --git a/src/view/com/modals/util.tsx b/src/view/com/modals/util.tsx deleted file mode 100644 index c047a0523c..0000000000 --- a/src/view/com/modals/util.tsx +++ /dev/null @@ -1,4 +0,0 @@ -export { - BottomSheetScrollView as ScrollView, - BottomSheetTextInput as TextInput, -} from '@discord/bottom-sheet/src' diff --git a/src/view/com/modals/util.web.tsx b/src/view/com/modals/util.web.tsx deleted file mode 100644 index acd10c2a60..0000000000 --- a/src/view/com/modals/util.web.tsx +++ /dev/null @@ -1 +0,0 @@ -export {ScrollView, TextInput} from 'react-native' diff --git a/src/view/com/util/BottomSheetCustomBackdrop.tsx b/src/view/com/util/BottomSheetCustomBackdrop.tsx deleted file mode 100644 index fc857338fd..0000000000 --- a/src/view/com/util/BottomSheetCustomBackdrop.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import {useMemo} from 'react' -import {TouchableWithoutFeedback} from 'react-native' -import Animated, { - Extrapolation, - interpolate, - useAnimatedStyle, -} from 'react-native-reanimated' -import {type BottomSheetBackdropProps} from '@discord/bottom-sheet/src' -import {msg} from '@lingui/core/macro' -import {useLingui} from '@lingui/react' - -export function createCustomBackdrop( - onClose?: () => void, -): React.FC { - const CustomBackdrop = ({animatedIndex, style}: BottomSheetBackdropProps) => { - const {_} = useLingui() - - // animated variables - const opacity = useAnimatedStyle(() => ({ - opacity: interpolate( - animatedIndex.get(), // current snap index - [-1, 0], // input range - [0, 0.5], // output range - Extrapolation.CLAMP, - ), - })) - - const containerStyle = useMemo( - () => [style, {backgroundColor: '#000'}, opacity], - [style, opacity], - ) - - return ( - { - if (onClose !== undefined) { - onClose() - } - }}> - - - ) - } - return CustomBackdrop -} diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx index 658a3ca3b3..b2647363ea 100644 --- a/src/view/com/util/Link.tsx +++ b/src/view/com/util/Link.tsx @@ -28,7 +28,6 @@ import { } from '#/lib/strings/url-helpers' import {type TypographyVariant} from '#/lib/ThemeContext' import {emitSoftReset} from '#/state/events' -import {useModalControls} from '#/state/modals' import {WebAuxClickWrapper} from '#/view/com/util/WebAuxClickWrapper' import {useTheme} from '#/alf' import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' @@ -79,7 +78,6 @@ export const Link = memo(function Link({ ...props }: Props) { const t = useTheme() - const {closeModal} = useModalControls() const navigation = useNavigationDeduped() const anchorHref = asAnchor ? sanitizeUrl(href) : undefined const openLink = useOpenLink() @@ -90,7 +88,6 @@ export const Link = memo(function Link({ onBeforePress?.() if (typeof href === 'string') { return onPressInner( - closeModal, navigation, sanitizeUrl(href), navigationAction, @@ -101,7 +98,6 @@ export const Link = memo(function Link({ } }, [ - closeModal, navigation, navigationAction, href, @@ -205,7 +201,6 @@ export const TextLink = memo(function TextLink({ onBeforePress?: () => void } & TextProps) { const navigation = useNavigationDeduped() - const {closeModal} = useModalControls() const {linkWarningDialogControl} = useGlobalDialogsControlContext() const openLink = useOpenLink() const groupChatJoinIntent = useGroupChatJoinIntent() @@ -246,7 +241,6 @@ export const TextLink = memo(function TextLink({ return onPressProp() } return onPressInner( - closeModal, navigation, sanitizeUrl(href), navigationAction, @@ -258,7 +252,6 @@ export const TextLink = memo(function TextLink({ [ onBeforePress, onPressProp, - closeModal, navigation, href, text, @@ -383,7 +376,6 @@ const EXEMPT_PATHS = ['/robots.txt', '/security.txt', '/.well-known/'] // needed customizations // -prf function onPressInner( - closeModal = () => {}, navigation: DebouncedNavigationProp, href: string, navigationAction: 'push' | 'replace' | 'navigate' = 'push', @@ -429,8 +421,6 @@ function onPressInner( ) { openLink(href) } else { - closeModal() // close any active modals - const [routeName, params] = router.matchPath(href) if (navigationAction === 'push') { // @ts-ignore we're not able to type check on this one -prf diff --git a/src/view/shell/Composer.web.tsx b/src/view/shell/Composer.web.tsx index fc87660e14..d7d0e4ed84 100644 --- a/src/view/shell/Composer.web.tsx +++ b/src/view/shell/Composer.web.tsx @@ -3,7 +3,6 @@ import {DismissableLayer, FocusGuards, FocusScope} from 'radix-ui/internal' import {RemoveScrollBar} from 'react-remove-scroll-bar' import {useA11y} from '#/state/a11y' -import {useModals} from '#/state/modals' import {type ComposerOpts, useComposerState} from '#/state/shell/composer' import {ComposePost, useComposerCancelRef} from '#/view/com/composer/Composer' import {atoms as a, flatten, useBreakpoints, useTheme} from '#/alf' @@ -28,7 +27,6 @@ export function Composer() { function Inner({state}: {state: ComposerOpts}) { const ref = useComposerCancelRef() - const {isModalActive} = useModals() const t = useTheme() const {gtMobile} = useBreakpoints() const {reduceMotionEnabled} = useA11y() @@ -51,12 +49,7 @@ function Inner({state}: {state: ComposerOpts}) { ])} onFocusOutside={evt => evt.preventDefault()} onInteractOutside={evt => evt.preventDefault()} - onDismiss={() => { - // TEMP: remove when all modals are ALF'd -sfn - if (!isModalActive) { - ref.current?.onPressCancel() - } - }}> + onDismiss={() => ref.current?.onPressCancel()}> - diff --git a/src/view/shell/index.web.tsx b/src/view/shell/index.web.tsx index 62dec9bcf7..6a68530f05 100644 --- a/src/view/shell/index.web.tsx +++ b/src/view/shell/index.web.tsx @@ -10,7 +10,6 @@ import {type NavigationProp} from '#/lib/routes/types' import {useSession} from '#/state/session' import {useIsDrawerOpen, useSetDrawerOpen} from '#/state/shell' import {useCloseAllActiveElements} from '#/state/util' -import {ModalsContainer} from '#/view/com/modals/Modal' import {ErrorBoundary} from '#/view/com/util/ErrorBoundary' import {Deactivated} from '#/screens/Deactivated' import {Takendown} from '#/screens/Takendown' @@ -65,7 +64,6 @@ function ShellInner() { -