diff --git a/patches/@gorhom+bottom-sheet+4.6.4.patch b/patches/@gorhom+bottom-sheet+4.6.4.patch new file mode 100644 index 000000000..a83ca8885 --- /dev/null +++ b/patches/@gorhom+bottom-sheet+4.6.4.patch @@ -0,0 +1,32 @@ +diff --git a/node_modules/@gorhom/bottom-sheet/lib/typescript/types.d.ts b/node_modules/@gorhom/bottom-sheet/lib/typescript/types.d.ts +index 27f39a1..74223d9 100644 +--- a/node_modules/@gorhom/bottom-sheet/lib/typescript/types.d.ts ++++ b/node_modules/@gorhom/bottom-sheet/lib/typescript/types.d.ts +@@ -91,6 +91,14 @@ export interface BottomSheetModalMethods extends BottomSheetMethods { + * @see {WithTimingConfig} + */ + dismiss: (animationConfigs?: WithSpringConfig | WithTimingConfig) => void; ++ /** ++ * Get the current index of the bottom sheet modal. ++ */ ++ getCurrentIndex: () => number; ++ /** ++ * Check if the bottom sheet modal is open. ++ */ ++ isOpen: boolean; + } + //#endregion + +diff --git a/node_modules/@gorhom/bottom-sheet/src/components/bottomSheetModal/BottomSheetModal.tsx b/node_modules/@gorhom/bottom-sheet/src/components/bottomSheetModal/BottomSheetModal.tsx +index 275ce50..80cd2b8 100644 +--- a/node_modules/@gorhom/bottom-sheet/src/components/bottomSheetModal/BottomSheetModal.tsx ++++ b/node_modules/@gorhom/bottom-sheet/src/components/bottomSheetModal/BottomSheetModal.tsx +@@ -363,6 +363,8 @@ const BottomSheetModalComponent = forwardRef< + // internal + minimize: handleMinimize, + restore: handleRestore, ++ getCurrentIndex: () => currentIndexRef.current, ++ isOpen: animateOnMount ? currentIndexRef.current !== -1 : false, + })); + //#endregion + diff --git a/src/App.tsx b/src/App.tsx index 457d43465..f6b8c272f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -15,7 +15,6 @@ import { ThemeProvider } from 'styled-components/native'; import './utils/i18n'; import './utils/quick-actions'; import AppOnboarded from './AppOnboarded'; -import { SlashtagsProvider } from './components/SlashtagsProvider'; import { toastConfig } from './components/Toast'; import { useAppSelector } from './hooks/redux'; import AppUpdate from './screens/AppUpdate'; @@ -78,9 +77,7 @@ const App = (): ReactElement => { ) : hasCriticalUpdate ? ( ) : walletExists && !requiresRemoteRestore ? ( - - - + ) : ( diff --git a/src/AppOnboarded.tsx b/src/AppOnboarded.tsx index f91e4cd65..e214f34c5 100644 --- a/src/AppOnboarded.tsx +++ b/src/AppOnboarded.tsx @@ -1,8 +1,12 @@ +import { BottomSheetModalProvider } from '@gorhom/bottom-sheet'; import React, { memo, ReactElement } from 'react'; + import InactivityTracker from './components/InactivityTracker'; +import { SlashtagsProvider } from './components/SlashtagsProvider'; import { useAppStateHandler } from './hooks/useAppStateHandler'; import { useNetworkConnectivity } from './hooks/useNetworkConnectivity'; import { useWalletStartup } from './hooks/useWalletStartup'; +import { SheetRefsProvider } from './navigation/bottom-sheet/SheetRefsProvider'; import DrawerNavigator from './navigation/root/DrawerNavigator'; import RootNavigationContainer from './navigation/root/RootNavigationContainer'; @@ -12,11 +16,17 @@ const AppOnboarded = (): ReactElement => { useNetworkConnectivity(); return ( - - - - - + + + + + + + + + + + ); }; diff --git a/src/components/BottomSheetWrapper.tsx b/src/components/BottomSheetWrapper.tsx index 6e25f9aee..2e26d6b08 100644 --- a/src/components/BottomSheetWrapper.tsx +++ b/src/components/BottomSheetWrapper.tsx @@ -1,188 +1,107 @@ -/*********************************************************************************** - * This component wraps the @gorhom/bottom-sheet library - * to more easily take advantage of it throughout the app. - * - * Implementation: - * const snapPoints = useSnapPoints('medium'); - * - * - * ... - * - * - * Usage Throughout App: - * dispatch(showBottomSheet('viewName')); - * dispatch(showBottomSheet('viewName', { option1: 'value' })); - * dispatch(closeSheet('viewName')); - * - * Check if a given view is open: - * getStore().user.viewController['viewName'].isOpen; - ***********************************************************************************/ - -import BottomSheet, { - BottomSheetView, +import { BottomSheetBackdrop, - BottomSheetBackgroundProps, BottomSheetBackdropProps, + BottomSheetBackgroundProps, + BottomSheetModal, + BottomSheetView, } from '@gorhom/bottom-sheet'; -import React, { - memo, - ReactElement, - forwardRef, - useImperativeHandle, - useRef, - useEffect, - useCallback, - useMemo, - useState, -} from 'react'; +import React, { ReactNode, useCallback, useMemo } from 'react'; import { StyleSheet } from 'react-native'; import { useReducedMotion } from 'react-native-reanimated'; -import { useTheme } from 'styled-components/native'; import { __E2E__ } from '../constants/env'; -import { useAppDispatch, useAppSelector } from '../hooks/redux'; -import { viewControllerSelector } from '../store/reselect/ui'; +import useColors from '../hooks/colors'; +import { useAppDispatch } from '../hooks/redux'; +import { + SheetId, + useSheetRef, +} from '../navigation/bottom-sheet/SheetRefsProvider'; import { closeSheet } from '../store/slices/ui'; -import { TViewController } from '../store/types/ui'; import BottomSheetBackground from './BottomSheetBackground'; -export interface BottomSheetWrapperProps { - children: ReactElement; - view: TViewController; +type SheetProps = { + view: SheetId; snapPoints: number[]; - backdrop?: boolean; + children: ReactNode; testID?: string; onOpen?: () => void; onClose?: () => void; -} - -const BottomSheetWrapper = forwardRef( - ( - { - children, - view, - snapPoints, - backdrop = true, - testID, - onOpen, - onClose, - }: BottomSheetWrapperProps, - ref, - ): ReactElement => { - const bottomSheetRef = useRef(null); - const reducedMotion = useReducedMotion(); - const dispatch = useAppDispatch(); - const data = useAppSelector((state) => viewControllerSelector(state, view)); - const theme = useTheme(); - const handleIndicatorStyle = useMemo( - () => ({ backgroundColor: theme.colors.gray2 }), - [theme.colors.gray2], +}; + +const Sheet = ({ + view, + snapPoints, + children, + testID, + onOpen, + onClose, +}: SheetProps) => { + const colors = useColors(); + const sheetRef = useSheetRef(view); + const isReducedMotion = useReducedMotion(); + const dispatch = useAppDispatch(); + + // https://github.com/gorhom/react-native-bottom-sheet/issues/770#issuecomment-1072113936 + // do not activate BottomSheet if swipe horizontally, this allows using Swiper inside of it + const activeOffsetX = useMemo(() => [-999, 999], []); + const activeOffsetY = useMemo(() => [-10, 10], []); + + const backdropComponent = useCallback((props: BottomSheetBackdropProps) => { + return ( + ); - const [mounted, setMounted] = useState(false); - - // https://github.com/gorhom/react-native-bottom-sheet/issues/770#issuecomment-1072113936 - // do not activate BottomSheet if swipe horizontally, this allows using Swiper inside of it - const activeOffsetX = useMemo(() => [-999, 999], []); - const activeOffsetY = useMemo(() => [-10, 10], []); - - useEffect(() => { - if (data.isOpen) { - bottomSheetRef.current?.snapToIndex(0); - } else { - bottomSheetRef.current?.close(); - } - setTimeout(() => setMounted(true), 500); - }, [data.isOpen]); - - useImperativeHandle(ref, () => ({ - snapToIndex(index = 0): void { - bottomSheetRef.current?.snapToIndex(index); - }, - expand(): void { - bottomSheetRef.current?.snapToIndex(1); - }, - close(): void { - bottomSheetRef.current?.close(); - }, - })); - - const _onOpen = useCallback(() => onOpen?.(), [onOpen]); - - const _onClose = useCallback(() => { - if (data.isOpen) { + }, []); + + const backgroundComponent = useCallback( + ({ style }: BottomSheetBackgroundProps) => ( + + ), + [], + ); + + const onChange = useCallback( + (index: number) => { + if (index === -1) { + onClose?.(); + // reset sheet params dispatch(closeSheet(view)); + } else if (index >= 0) { + onOpen?.(); } - onClose?.(); - }, [data.isOpen, view, onClose, dispatch]); - - // callbacks - const handleSheetChanges = useCallback( - (index: number) => { - if (index === -1) { - _onClose(); - } else if (index >= 0) { - _onOpen(); - } - }, - [_onClose, _onOpen], - ); - - const renderBackdrop = useCallback( - (props: BottomSheetBackdropProps) => { - if (!backdrop) { - return null; - } - return ( - - ); - }, - [backdrop], - ); - - const backgroundComponent = useCallback( - ({ style }: BottomSheetBackgroundProps) => ( - - ), - [], - ); - - const style = useMemo( - () => [styles.container, !mounted && { minHeight: snapPoints[0] - 30 }], - [snapPoints, mounted], - ); - - // Determine initial snapPoint index based on provided data. - const index = useMemo((): number => (data.isOpen ? 0 : -1), [data.isOpen]); - - return ( - - - {children} - - - ); - }, -); + }, + [onOpen, onClose, dispatch, view], + ); + + return ( + + + {children} + + + ); +}; const styles = StyleSheet.create({ container: { @@ -198,4 +117,4 @@ const styles = StyleSheet.create({ }, }); -export default memo(BottomSheetWrapper); +export default Sheet; diff --git a/src/components/BottomSheetWrapper_old.tsx b/src/components/BottomSheetWrapper_old.tsx new file mode 100644 index 000000000..57571fcea --- /dev/null +++ b/src/components/BottomSheetWrapper_old.tsx @@ -0,0 +1,167 @@ +/*********************************************************************************** + * This component wraps the @gorhom/bottom-sheet library + * to more easily take advantage of it throughout the app. + * + * Implementation: + * const snapPoints = useSnapPoints('medium'); + * + * + * ... + * + * + * Usage Throughout App: + * dispatch(showBottomSheet('viewName')); + * dispatch(showBottomSheet('viewName', { option1: 'value' })); + * dispatch(closeSheet('viewName')); + * + * Check if a given view is open: + * getStore().user.viewController['viewName'].isOpen; + ***********************************************************************************/ + +import BottomSheet, { BottomSheetView } from '@gorhom/bottom-sheet'; +import React, { + memo, + ReactElement, + forwardRef, + useImperativeHandle, + useRef, + useEffect, + useCallback, + useMemo, + useState, +} from 'react'; +import { StyleSheet } from 'react-native'; +import { useReducedMotion } from 'react-native-reanimated'; +import { useTheme } from 'styled-components/native'; + +import { __E2E__ } from '../constants/env'; +import { useAppDispatch, useAppSelector } from '../hooks/redux'; +import { viewControllerSelector } from '../store/reselect/ui'; +import { closeSheet } from '../store/slices/ui'; +import { TViewController } from '../store/types/ui'; + +export interface BottomSheetWrapperProps { + children: ReactElement; + view: TViewController; + snapPoints: number[]; + testID?: string; + onOpen?: () => void; + onClose?: () => void; +} + +const BottomSheetWrapper = forwardRef( + ( + { + children, + view, + snapPoints, + testID, + onOpen, + onClose, + }: BottomSheetWrapperProps, + ref, + ): ReactElement => { + const bottomSheetRef = useRef(null); + const reducedMotion = useReducedMotion(); + const dispatch = useAppDispatch(); + const data = useAppSelector((state) => viewControllerSelector(state, view)); + const theme = useTheme(); + const handleIndicatorStyle = useMemo( + () => ({ backgroundColor: theme.colors.gray2 }), + [theme.colors.gray2], + ); + const [mounted, setMounted] = useState(false); + + // https://github.com/gorhom/react-native-bottom-sheet/issues/770#issuecomment-1072113936 + // do not activate BottomSheet if swipe horizontally, this allows using Swiper inside of it + const activeOffsetX = useMemo(() => [-999, 999], []); + const activeOffsetY = useMemo(() => [-10, 10], []); + + useEffect(() => { + if (data.isOpen) { + bottomSheetRef.current?.snapToIndex(0); + } else { + bottomSheetRef.current?.close(); + } + setTimeout(() => setMounted(true), 500); + }, [data.isOpen]); + + useImperativeHandle(ref, () => ({ + snapToIndex(index = 0): void { + bottomSheetRef.current?.snapToIndex(index); + }, + expand(): void { + bottomSheetRef.current?.snapToIndex(1); + }, + close(): void { + bottomSheetRef.current?.close(); + }, + })); + + const _onOpen = useCallback(() => onOpen?.(), [onOpen]); + + const _onClose = useCallback(() => { + if (data.isOpen) { + dispatch(closeSheet(view)); + } + onClose?.(); + }, [data.isOpen, view, onClose, dispatch]); + + // callbacks + const handleSheetChanges = useCallback( + (index: number) => { + if (index === -1) { + _onClose(); + } else if (index >= 0) { + _onOpen(); + } + }, + [_onClose, _onOpen], + ); + + const style = useMemo( + () => [styles.container, !mounted && { minHeight: snapPoints[0] - 30 }], + [snapPoints, mounted], + ); + + // Determine initial snapPoint index based on provided data. + const index = useMemo((): number => (data.isOpen ? 0 : -1), [data.isOpen]); + + return ( + + + {children} + + + ); + }, +); + +const styles = StyleSheet.create({ + container: { + borderTopLeftRadius: 32, + borderTopRightRadius: 32, + height: '100%', + position: 'relative', + }, + handle: { + alignSelf: 'center', + height: 32, + width: 32, + }, +}); + +export default memo(BottomSheetWrapper); diff --git a/src/components/SlashtagsProvider.tsx b/src/components/SlashtagsProvider.tsx index 02963675c..5894dc204 100644 --- a/src/components/SlashtagsProvider.tsx +++ b/src/components/SlashtagsProvider.tsx @@ -3,8 +3,7 @@ import SlashtagsProfile from '@synonymdev/slashtags-profile'; import { format, parse } from '@synonymdev/slashtags-url'; import type { Client as IWebRelayClient } from '@synonymdev/web-relay'; import { Client, Store } from '@synonymdev/web-relay/lib/client'; -import React, { ReactElement, useEffect, useState } from 'react'; -import { createContext } from 'react'; +import React, { ReactElement, createContext, useEffect, useState } from 'react'; import { useAppSelector } from '../hooks/redux'; import { WebRelayCache } from '../storage'; diff --git a/src/components/TabBar.tsx b/src/components/TabBar.tsx index 0cc6b47dd..f94271a80 100644 --- a/src/components/TabBar.tsx +++ b/src/components/TabBar.tsx @@ -1,26 +1,25 @@ import { useNavigation } from '@react-navigation/native'; -import React, { ReactElement, useMemo } from 'react'; +import React, { ReactElement, useMemo, memo } from 'react'; import { useTranslation } from 'react-i18next'; import { Platform, Pressable, StyleProp, StyleSheet, + View, ViewStyle, } from 'react-native'; -import Animated, { FadeIn } from 'react-native-reanimated'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { receiveIcon, sendIcon } from '../assets/icons/tabs'; import useColors from '../hooks/colors'; import { useAppSelector } from '../hooks/redux'; +import { useSheetRef } from '../navigation/bottom-sheet/SheetRefsProvider'; import { rootNavigation } from '../navigation/root/RootNavigationContainer'; import type { RootNavigationProp } from '../navigation/types'; import { resetSendTransaction } from '../store/actions/wallet'; import { spendingOnboardingSelector } from '../store/reselect/aggregations'; -import { viewControllersSelector } from '../store/reselect/ui'; -import { TViewController } from '../store/types/ui'; -import { toggleBottomSheet } from '../store/utils/ui'; +import { showBottomSheet } from '../store/utils/ui'; import { ScanIcon } from '../styles/icons'; import ButtonBlur from './buttons/ButtonBlur'; @@ -29,38 +28,25 @@ const TabBar = (): ReactElement => { const insets = useSafeAreaInsets(); const { t } = useTranslation('wallet'); const navigation = useNavigation(); - const viewControllers = useAppSelector(viewControllersSelector); + const sendSheetRef = useSheetRef('sendNavigation'); + const receiveSheetRef = useSheetRef('receiveNavigation'); const isSpendingOnboarding = useAppSelector(spendingOnboardingSelector); - const shouldHide = useMemo(() => { - const viewControllerKeys: TViewController[] = [ - 'backupPrompt', - 'PINNavigation', - 'highBalance', - 'appUpdatePrompt', - 'timeRangePrompt', - 'tagsPrompt', - ]; - return viewControllerKeys.some((view) => viewControllers[view].isOpen); - }, [viewControllers]); - const onReceivePress = (): void => { const currentRoute = rootNavigation.getCurrentRoute(); // if we are on the spending screen and the user has not yet received funds if (currentRoute === 'ActivitySpending' && isSpendingOnboarding) { - toggleBottomSheet('receiveNavigation', { - receiveScreen: 'ReceiveAmount', - }); + showBottomSheet('receiveNavigation', { receiveScreen: 'ReceiveAmount' }); } else { - toggleBottomSheet('receiveNavigation'); + receiveSheetRef.current?.present(); } }; const onSendPress = (): void => { // make sure we start with a clean transaction state resetSendTransaction(); - toggleBottomSheet('sendNavigation'); + sendSheetRef.current?.present(); }; const onScanPress = (): void => navigation.navigate('Scanner'); @@ -82,12 +68,8 @@ const TabBar = (): ReactElement => { const sendXml = sendIcon('white'); const receiveXml = receiveIcon('white'); - if (shouldHide) { - return <>; - } - return ( - + { testID="Receive" onPress={onReceivePress} /> - + ); }; @@ -149,4 +131,4 @@ const styles = StyleSheet.create({ }, }); -export default TabBar; +export default memo(TabBar); diff --git a/src/hooks/bottomSheet.ts b/src/hooks/bottomSheet.ts index 6b73e55b7..d02cd9e73 100644 --- a/src/hooks/bottomSheet.ts +++ b/src/hooks/bottomSheet.ts @@ -10,10 +10,11 @@ import { viewControllerIsOpenSelector, viewControllersSelector, } from '../store/reselect/ui'; -import { closeAllSheets, closeSheet } from '../store/slices/ui'; import { TViewController } from '../store/types/ui'; +// import { closeAllSheets, closeSheet } from '../store/slices/ui'; +import { closeAllSheets, closeSheet } from '../store/utils/ui'; import { objectKeys } from '../utils/objectKeys'; -import { useAppDispatch, useAppSelector } from './redux'; +import { useAppSelector } from './redux'; export const useSnapPoints = ( size: 'small' | 'medium' | 'large' | 'calendar', @@ -56,7 +57,7 @@ export const useSnapPoints = ( export const useBottomSheetBackPress = ( viewController: TViewController, ): void => { - const dispatch = useAppDispatch(); + // const dispatch = useAppDispatch(); const isBottomSheetOpen = useAppSelector((state) => { return viewControllerIsOpenSelector(state, viewController); }); @@ -73,7 +74,8 @@ export const useBottomSheetBackPress = ( backHandlerSubscriptionRef.current = BackHandler.addEventListener( 'hardwareBackPress', () => { - dispatch(closeSheet(viewController)); + // dispatch(closeSheet(viewController)); + closeSheet(viewController); return true; }, ); @@ -82,7 +84,7 @@ export const useBottomSheetBackPress = ( backHandlerSubscriptionRef.current?.remove(); backHandlerSubscriptionRef.current = null; }; - }, [isBottomSheetOpen, viewController, dispatch]); + }, [isBottomSheetOpen, viewController]); }; /** @@ -90,7 +92,7 @@ export const useBottomSheetBackPress = ( * for screens that are part of a navigator nested in a bottom sheet */ export const useBottomSheetScreenBackPress = (): void => { - const dispatch = useAppDispatch(); + // const dispatch = useAppDispatch(); const navigation = useNavigation(); const viewControllers = useAppSelector(viewControllersSelector); @@ -115,7 +117,7 @@ export const useBottomSheetScreenBackPress = (): void => { if (navigation.canGoBack()) { navigation.goBack(); } else { - dispatch(closeAllSheets()); + closeAllSheets(); } return true; }, @@ -125,6 +127,6 @@ export const useBottomSheetScreenBackPress = (): void => { backHandlerSubscriptionRef.current?.remove(); backHandlerSubscriptionRef.current = null; }; - }, [dispatch, isBottomSheetOpen, navigation]), + }, [isBottomSheetOpen, navigation]), ); }; diff --git a/src/navigation/bottom-sheet/AppUpdatePrompt.tsx b/src/navigation/bottom-sheet/AppUpdatePrompt.tsx index 19e845302..56dbcefea 100644 --- a/src/navigation/bottom-sheet/AppUpdatePrompt.tsx +++ b/src/navigation/bottom-sheet/AppUpdatePrompt.tsx @@ -14,9 +14,8 @@ import { viewControllersSelector, } from '../../store/reselect/ui'; import { ignoreAppUpdateTimestampSelector } from '../../store/reselect/user'; -import { closeSheet } from '../../store/slices/ui'; import { ignoreAppUpdate } from '../../store/slices/user'; -import { showBottomSheet } from '../../store/utils/ui'; +import { closeSheet, showBottomSheet } from '../../store/utils/ui'; import { Display } from '../../styles/text'; import { openURL } from '../../utils/helpers'; import { objectKeys } from '../../utils/objectKeys'; @@ -78,13 +77,13 @@ const AppUpdatePrompt = (): ReactElement => { const onCancel = (): void => { dispatch(ignoreAppUpdate()); - dispatch(closeSheet('appUpdatePrompt')); + closeSheet('appUpdatePrompt'); }; const onUpdate = async (): Promise => { dispatch(ignoreAppUpdate()); await openURL(updateInfo?.url!); - dispatch(closeSheet('appUpdatePrompt')); + closeSheet('appUpdatePrompt'); }; return ( diff --git a/src/navigation/bottom-sheet/BackupPrompt.tsx b/src/navigation/bottom-sheet/BackupPrompt.tsx index ccbd6fa1b..f1808a1fd 100644 --- a/src/navigation/bottom-sheet/BackupPrompt.tsx +++ b/src/navigation/bottom-sheet/BackupPrompt.tsx @@ -13,43 +13,46 @@ import { useBalance } from '../../hooks/wallet'; import { viewControllersSelector } from '../../store/reselect/ui'; import { backupVerifiedSelector } from '../../store/reselect/user'; import { ignoreBackupTimestampSelector } from '../../store/reselect/user'; -import { closeSheet } from '../../store/slices/ui'; import { ignoreBackup } from '../../store/slices/user'; -import { showBottomSheet } from '../../store/utils/ui'; import { Display } from '../../styles/text'; import { objectKeys } from '../../utils/objectKeys'; +import { useSheetRef } from './SheetRefsProvider'; const imageSrc = require('../../assets/illustrations/safe.png'); const ASK_INTERVAL = 1000 * 60 * 60 * 24; // 1 day - how long this prompt will be hidden if user taps Later const CHECK_DELAY = 2000; // how long user needs to stay on Wallets screen before he will see this prompt +const sheetId = 'backupPrompt'; + const BackupPrompt = (): ReactElement => { + const dispatch = useAppDispatch(); const { t } = useTranslation('security'); + const sheetRef = useSheetRef(sheetId); + const backupNavigationSheetRef = useSheetRef('backupNavigation'); const snapPoints = useSnapPoints('medium'); - const dispatch = useAppDispatch(); const viewControllers = useAppSelector(viewControllersSelector); const ignoreTimestamp = useAppSelector(ignoreBackupTimestampSelector); const backupVerified = useAppSelector(backupVerifiedSelector); const { totalBalance } = useBalance(); - useBottomSheetBackPress('backupPrompt'); + useBottomSheetBackPress(sheetId); const anyBottomSheetIsOpen = useMemo(() => { const viewControllerKeys = objectKeys(viewControllers); return viewControllerKeys - .filter((view) => view !== 'backupPrompt') + .filter((view) => view !== sheetId) .some((view) => viewControllers[view].isOpen); }, [viewControllers]); const handleLater = (): void => { dispatch(ignoreBackup()); - dispatch(closeSheet('backupPrompt')); + sheetRef.current?.close(); }; const handleBackup = (): void => { - dispatch(closeSheet('backupPrompt')); - showBottomSheet('backupNavigation'); + sheetRef.current?.close(); + backupNavigationSheetRef.current?.present(); }; // if backup has not been verified @@ -68,13 +71,14 @@ const BackupPrompt = (): ReactElement => { ); }, [backupVerified, totalBalance, ignoreTimestamp, anyBottomSheetIsOpen]); + // biome-ignore lint/correctness/useExhaustiveDependencies: sheetRef doesn't change useEffect(() => { if (!shouldShowBottomSheet) { return; } const timer = setTimeout(() => { - showBottomSheet('backupPrompt'); + sheetRef.current?.present(); }, CHECK_DELAY); return (): void => { @@ -86,7 +90,7 @@ const BackupPrompt = (): ReactElement => { return ( { dispatch(ignoreBackup()); diff --git a/src/navigation/bottom-sheet/BottomSheets.tsx b/src/navigation/bottom-sheet/BottomSheets.tsx index 782d1ed06..b545a05b0 100644 --- a/src/navigation/bottom-sheet/BottomSheets.tsx +++ b/src/navigation/bottom-sheet/BottomSheets.tsx @@ -1,6 +1,6 @@ import React, { JSX, memo } from 'react'; -import { useAppSelector } from '../../hooks/redux'; -import { viewControllersSelector } from '../../store/reselect/ui'; +// import { useAppSelector } from '../../hooks/redux'; +// import { viewControllersSelector } from '../../store/reselect/ui'; // import TransferFailed from '../bottom-sheet/TransferFailed'; import BoostPrompt from '../../screens/Wallets/BoostPrompt'; @@ -16,21 +16,21 @@ import ReceiveNavigation from './ReceiveNavigation'; import SendNavigation from './SendNavigation'; const BottomSheets = (): JSX.Element => { - const views = useAppSelector(viewControllersSelector); + // const views = useAppSelector(viewControllersSelector); return ( <> - {views.backupNavigation.isMounted && } - {views.boostPrompt.isMounted && } - {views.connectionClosed.isMounted && } - {views.lnurlWithdraw.isMounted && } - {views.newTxPrompt.isMounted && } - {views.orangeTicket.isMounted && } - {views.PINNavigation.isMounted && } - {views.receiveNavigation.isMounted && } - {views.sendNavigation.isMounted && } - {/* {views.treasureHunt.isMounted && } */} - {views.pubkyAuth.isMounted && } + + + + + + + + + + {/* */} + ); }; diff --git a/src/navigation/bottom-sheet/ConnectionClosed.tsx b/src/navigation/bottom-sheet/ConnectionClosed.tsx index 4b011e6cb..5f32386c8 100644 --- a/src/navigation/bottom-sheet/ConnectionClosed.tsx +++ b/src/navigation/bottom-sheet/ConnectionClosed.tsx @@ -10,21 +10,19 @@ import { useBottomSheetBackPress, useSnapPoints, } from '../../hooks/bottomSheet'; -import { useAppDispatch } from '../../hooks/redux'; -import { closeSheet } from '../../store/slices/ui'; +import { closeSheet } from '../../store/utils/ui'; import { BodyM } from '../../styles/text'; const imageSrc = require('../../assets/illustrations/switch.png'); const ConnectionClosed = (): ReactElement => { const { t } = useTranslation('lightning'); - const dispatch = useAppDispatch(); const snapPoints = useSnapPoints('medium'); useBottomSheetBackPress('backupPrompt'); const onContinue = (): void => { - dispatch(closeSheet('connectionClosed')); + closeSheet('connectionClosed'); }; return ( diff --git a/src/navigation/bottom-sheet/ForceTransfer.tsx b/src/navigation/bottom-sheet/ForceTransfer.tsx index 3450ec8f0..36cdd6622 100644 --- a/src/navigation/bottom-sheet/ForceTransfer.tsx +++ b/src/navigation/bottom-sheet/ForceTransfer.tsx @@ -9,9 +9,8 @@ import { } from '../../hooks/bottomSheet'; import { useAppDispatch, useAppSelector } from '../../hooks/redux'; import { startCoopCloseTimestampSelector } from '../../store/reselect/user'; -import { closeSheet } from '../../store/slices/ui'; import { clearCoopCloseTimer } from '../../store/slices/user'; -import { showBottomSheet } from '../../store/utils/ui'; +import { closeSheet, showBottomSheet } from '../../store/utils/ui'; import { Display } from '../../styles/text'; import { closeAllChannels } from '../../utils/lightning'; import { showToast } from '../../utils/notifications'; @@ -76,7 +75,7 @@ const ForceTransfer = (): ReactElement => { }, [startTime, dispatch]); const onCancel = (): void => { - dispatch(closeSheet('forceTransfer')); + closeSheet('forceTransfer'); }; const onContinue = async (): Promise => { @@ -102,7 +101,7 @@ const ForceTransfer = (): ReactElement => { title: t('force_init_title'), description: t('force_init_msg'), }); - dispatch(closeSheet('forceTransfer')); + closeSheet('forceTransfer'); } else { showToast({ type: 'warning', diff --git a/src/navigation/bottom-sheet/HighBalanceWarning.tsx b/src/navigation/bottom-sheet/HighBalanceWarning.tsx index 63fc0fa2a..86124b8aa 100644 --- a/src/navigation/bottom-sheet/HighBalanceWarning.tsx +++ b/src/navigation/bottom-sheet/HighBalanceWarning.tsx @@ -16,9 +16,8 @@ import { ignoreHighBalanceTimestampSelector, } from '../../store/reselect/user'; import { exchangeRatesSelector } from '../../store/reselect/wallet'; -import { closeSheet } from '../../store/slices/ui'; import { MAX_WARNINGS, ignoreHighBalance } from '../../store/slices/user'; -import { showBottomSheet } from '../../store/utils/ui'; +import { closeSheet, showBottomSheet } from '../../store/utils/ui'; import { BodyMB, Display } from '../../styles/text'; import { getFiatDisplayValues } from '../../utils/displayValues'; import { openURL } from '../../utils/helpers'; @@ -98,7 +97,7 @@ const HighBalanceWarning = (): ReactElement => { const onDismiss = (): void => { dispatch(ignoreHighBalance(true)); - dispatch(closeSheet('highBalance')); + closeSheet('highBalance'); }; return ( diff --git a/src/navigation/bottom-sheet/PubkyAuth.tsx b/src/navigation/bottom-sheet/PubkyAuth.tsx index 9b919ac89..732cbb39a 100644 --- a/src/navigation/bottom-sheet/PubkyAuth.tsx +++ b/src/navigation/bottom-sheet/PubkyAuth.tsx @@ -1,15 +1,16 @@ +import { auth, parseAuthUrl } from '@synonymdev/react-native-pubky'; import React, { memo, ReactElement, useCallback, useEffect, useMemo, + useState, } from 'react'; import { useTranslation } from 'react-i18next'; import { StyleSheet, View } from 'react-native'; - -import { auth, parseAuthUrl } from '@synonymdev/react-native-pubky'; import Animated, { FadeIn } from 'react-native-reanimated'; + import BottomSheetNavigationHeader from '../../components/BottomSheetNavigationHeader'; import BottomSheetWrapper from '../../components/BottomSheetWrapper'; import SafeAreaInset from '../../components/SafeAreaInset'; @@ -19,12 +20,11 @@ import { useSnapPoints, } from '../../hooks/bottomSheet'; import { useAppSelector } from '../../hooks/redux'; -import { dispatch } from '../../store/helpers.ts'; -import { viewControllerSelector } from '../../store/reselect/ui.ts'; -import { closeSheet } from '../../store/slices/ui.ts'; -import { CheckCircleIcon } from '../../styles/icons.ts'; +import { viewControllerSelector } from '../../store/reselect/ui'; +import { closeSheet } from '../../store/utils/ui'; +import { CheckCircleIcon } from '../../styles/icons'; import { BodyM, CaptionB, Text13UP, Title } from '../../styles/text'; -import { showToast } from '../../utils/notifications.ts'; +import { showToast } from '../../utils/notifications'; import { getPubkySecretKey } from '../../utils/pubky'; const defaultParsedUrl: PubkyAuthDetails = { @@ -87,10 +87,9 @@ const PubkyAuth = (): ReactElement => { const { url = '' } = useAppSelector((state) => { return viewControllerSelector(state, 'pubkyAuth'); }); - const [parsed, setParsed] = - React.useState(defaultParsedUrl); - const [authorizing, setAuthorizing] = React.useState(false); - const [authSuccess, setAuthSuccess] = React.useState(false); + const [parsed, setParsed] = useState(defaultParsedUrl); + const [authorizing, setAuthorizing] = useState(false); + const [authSuccess, setAuthSuccess] = useState(false); useBottomSheetBackPress('pubkyAuth'); @@ -150,13 +149,6 @@ const PubkyAuth = (): ReactElement => { [t, url], ); - const onClose = useMemo( - () => (): void => { - dispatch(closeSheet('pubkyAuth')); - }, - [], - ); - const Buttons = useCallback(() => { if (authSuccess) { return ( @@ -164,7 +156,7 @@ const PubkyAuth = (): ReactElement => { style={styles.authorizeButton} text={t('authorization.success')} size="large" - onPress={onClose} + onPress={() => closeSheet('pubkyAuth')} /> ); } @@ -174,7 +166,7 @@ const PubkyAuth = (): ReactElement => { style={styles.closeButton} text={t('authorization.deny')} size="large" - onPress={onClose} + onPress={() => closeSheet('pubkyAuth')} />