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')}
/>