REF: SImplify navigation stack with 1 master
This commit is contained in:
parent
a906a30641
commit
a17405d0fb
@ -71,14 +71,46 @@ const NewWalletPanel: React.FC<NewWalletPanelProps> = ({ onPress }) => {
|
||||
: { paddingVertical: 16, paddingHorizontal: 24 },
|
||||
});
|
||||
|
||||
const scale = useRef(new Animated.Value(1)).current;
|
||||
|
||||
const handlePressIn = useCallback(() => {
|
||||
Animated.spring(scale, {
|
||||
toValue: 0.97,
|
||||
useNativeDriver: true,
|
||||
friction: 4,
|
||||
}).start();
|
||||
}, [scale]);
|
||||
|
||||
const handlePressOut = useCallback(() => {
|
||||
Animated.spring(scale, {
|
||||
toValue: 1,
|
||||
useNativeDriver: true,
|
||||
friction: 4,
|
||||
}).start();
|
||||
}, [scale]);
|
||||
|
||||
return (
|
||||
<Pressable accessibilityRole="button" testID="CreateAWallet" onPress={onPress} style={isLargeScreen ? {} : { width: itemWidth * 1.2 }}>
|
||||
<View
|
||||
<Pressable
|
||||
onPressIn={handlePressIn}
|
||||
onPressOut={handlePressOut}
|
||||
onPress={onPress}
|
||||
testID="CreateAWallet"
|
||||
style={({ pressed }) => [
|
||||
isLargeScreen ? {} : { width: itemWidth * 1.2 },
|
||||
{
|
||||
opacity: pressed ? 0.9 : 1.0,
|
||||
},
|
||||
]}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={loc.wallets.list_create_a_wallet}
|
||||
>
|
||||
<Animated.View
|
||||
style={[
|
||||
nStyles.container,
|
||||
nStylesHooks.container,
|
||||
{ backgroundColor: WalletGradient.createWallet() },
|
||||
isLargeScreen ? {} : { width: itemWidth },
|
||||
{ transform: [{ scale }] },
|
||||
]}
|
||||
>
|
||||
<Text style={[nStyles.addAWAllet, { color: colors.foregroundColor }]}>{loc.wallets.list_create_a_wallet}</Text>
|
||||
@ -86,7 +118,7 @@ const NewWalletPanel: React.FC<NewWalletPanelProps> = ({ onPress }) => {
|
||||
<View style={nStyles.button}>
|
||||
<Text style={[nStyles.buttonText, { color: colors.brandingColor }]}>{loc.wallets.list_create_a_button}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</Animated.View>
|
||||
</Pressable>
|
||||
);
|
||||
};
|
||||
|
||||
@ -7,17 +7,14 @@ import { requestCameraAuthorization } from '../helpers/scan-qr';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
// List of screens that require biometrics
|
||||
const requiresBiometrics = [
|
||||
'WalletExportRoot',
|
||||
'WalletXpubRoot',
|
||||
'ViewEditMultisigCosigners',
|
||||
'ExportMultisigCoordinationSetupRoot',
|
||||
];
|
||||
const requiresBiometrics = ['WalletExportRoot', 'WalletXpubRoot', 'ViewEditMultisigCosigners', 'ExportMultisigCoordinationSetupRoot'];
|
||||
|
||||
// List of screens that require wallet export to be saved
|
||||
const requiresWalletExportIsSaved = ['ReceiveDetailsRoot', 'WalletAddresses'];
|
||||
|
||||
export const useExtendedNavigation = <T extends NavigationProp<ParamListBase>>(): T => {
|
||||
export const useExtendedNavigation = <T extends NavigationProp<ParamListBase>>(): T & {
|
||||
navigateToWalletsList: () => void;
|
||||
} => {
|
||||
const originalNavigation = useNavigation<T>();
|
||||
const { wallets, saveToDisk } = useStorage();
|
||||
const { isBiometricUseEnabled } = useBiometrics();
|
||||
@ -56,17 +53,36 @@ export const useExtendedNavigation = <T extends NavigationProp<ParamListBase>>()
|
||||
|
||||
const proceedWithNavigation = () => {
|
||||
console.log('Proceeding with navigation to', screenName);
|
||||
|
||||
// Navigation logic based on current route and target screen
|
||||
if (navigationRef.current?.isReady()) {
|
||||
if (typeof screenOrOptions === 'string') {
|
||||
originalNavigation.navigate({ name: screenOrOptions, params, merge: options?.merge });
|
||||
// Get the current route - we need to know which navigator we're in
|
||||
const currentRoute = navigationRef.current.getCurrentRoute();
|
||||
const currentRouteName = currentRoute?.name;
|
||||
|
||||
// Handle specific cases for nested navigation
|
||||
if (currentRouteName === 'DrawerRoot') {
|
||||
// If we're in DrawerRoot and trying to navigate to a screen that exists in DetailViewStackScreensStack
|
||||
originalNavigation.navigate('DrawerRoot', {
|
||||
screen: 'DetailViewStackScreensStack',
|
||||
params: {
|
||||
screen: screenName,
|
||||
params: params
|
||||
}
|
||||
});
|
||||
} else {
|
||||
originalNavigation.navigate({ ...screenOrOptions, params, merge: options?.merge });
|
||||
// Normal navigation
|
||||
if (typeof screenOrOptions === 'string') {
|
||||
originalNavigation.navigate({ name: screenOrOptions, params, merge: options?.merge });
|
||||
} else {
|
||||
originalNavigation.navigate({ ...screenOrOptions, params, merge: options?.merge });
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(async () => {
|
||||
// NEW: If the current (active) screen is 'ScanQRCode', bypass all checks.
|
||||
// Skip checks for ScanQRCode screen
|
||||
const currentRouteName = navigationRef.current?.getCurrentRoute()?.name;
|
||||
if (currentRouteName === 'ScanQRCode') {
|
||||
proceedWithNavigation();
|
||||
@ -82,7 +98,6 @@ export const useExtendedNavigation = <T extends NavigationProp<ParamListBase>>()
|
||||
return;
|
||||
} else {
|
||||
console.error('Biometric authentication failed');
|
||||
// Do not proceed if authentication fails.
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -107,17 +122,15 @@ export const useExtendedNavigation = <T extends NavigationProp<ParamListBase>>()
|
||||
await saveToDisk();
|
||||
proceedWithNavigation();
|
||||
} catch (error) {
|
||||
// If there was an error (or the user cancelled), navigate to the wallet export screen.
|
||||
originalNavigation.navigate('WalletExportRoot', {
|
||||
screen: 'WalletExport',
|
||||
params: { walletID },
|
||||
});
|
||||
}
|
||||
return; // Do not proceed with the original navigation if reminder was shown.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If the target screen is ScanQRCode, request camera authorization.
|
||||
if (screenName === 'ScanQRCode') {
|
||||
await requestCameraAuthorization();
|
||||
}
|
||||
@ -138,9 +151,5 @@ export const useExtendedNavigation = <T extends NavigationProp<ParamListBase>>()
|
||||
navigateToWalletsList,
|
||||
}),
|
||||
[originalNavigation, enhancedNavigate, navigateToWalletsList],
|
||||
);
|
||||
) as T & { navigateToWalletsList: () => void };
|
||||
};
|
||||
|
||||
// Usage example:
|
||||
// type NavigationProps = NativeStackNavigationProp<SendDetailsStackParamList, 'SendDetails'>;
|
||||
// const navigation = useExtendedNavigation<NavigationProps>();
|
||||
@ -26,7 +26,7 @@ import WalletDetails from '../screen/wallets/WalletDetails';
|
||||
import GenerateWord from '../screen/wallets/generateWord';
|
||||
import SelectWallet from '../screen/wallets/SelectWallet';
|
||||
import WalletsList from '../screen/wallets/WalletsList';
|
||||
import { NavigationDefaultOptions, StatusBarLightOptions, DetailViewStack } from './index'; // Importing the navigator
|
||||
import { NavigationDefaultOptions, StatusBarLightOptions, DetailViewStack } from './index';
|
||||
import AddWalletStack from './AddWalletStack';
|
||||
import AztecoRedeemStackRoot from './AztecoRedeemStack';
|
||||
import PaymentCodesListComponent from './LazyLoadPaymentCodeStack';
|
||||
@ -62,8 +62,8 @@ import SelfTest from '../screen/settings/SelfTest';
|
||||
import ReleaseNotes from '../screen/settings/ReleaseNotes';
|
||||
import ToolsScreen from '../screen/settings/tools';
|
||||
import SettingsPrivacy from '../screen/settings/SettingsPrivacy';
|
||||
import { ScanQRCodeComponent } from './LazyLoadScanQRCodeStack';
|
||||
import { useIsLargeScreen } from '../hooks/useIsLargeScreen';
|
||||
import { ScanQRCodeComponent } from './LazyLoadScanQRCodeStack';
|
||||
import ScanLNDInvoiceRoot from './ScanLNDInvoiceStack';
|
||||
import { ViewEditMultisigCosignersComponent } from './LazyLoadViewEditMultisigCosignersStack';
|
||||
|
||||
@ -329,7 +329,6 @@ const DetailViewStackScreensStack = () => {
|
||||
<DetailViewStack.Screen name="LNDCreateInvoiceRoot" component={LNDCreateInvoiceRoot} options={NavigationDefaultOptions} />
|
||||
<DetailViewStack.Screen name="ScanLNDInvoiceRoot" component={ScanLNDInvoiceRoot} options={NavigationDefaultOptions} />
|
||||
<DetailViewStack.Screen name="AztecoRedeemRoot" component={AztecoRedeemStackRoot} options={NavigationDefaultOptions} />
|
||||
{/* screens */}
|
||||
<DetailViewStack.Screen
|
||||
name="WalletExportRoot"
|
||||
component={WalletExportStack}
|
||||
@ -340,12 +339,10 @@ const DetailViewStackScreensStack = () => {
|
||||
component={ExportMultisigCoordinationSetupStack}
|
||||
options={NavigationDefaultOptions}
|
||||
/>
|
||||
|
||||
<DetailViewStack.Screen
|
||||
name="ViewEditMultisigCosigners"
|
||||
component={ViewEditMultisigCosignersComponent}
|
||||
options={{ ...NavigationDefaultOptions, ...StatusBarLightOptions, gestureEnabled: false, fullScreenGestureEnabled: false }}
|
||||
initialParams={{ walletID: undefined, cosigners: undefined }}
|
||||
options={{ ...NavigationDefaultOptions, ...StatusBarLightOptions, gestureEnabled: false }}
|
||||
/>
|
||||
<DetailViewStack.Screen
|
||||
name="WalletXpubRoot"
|
||||
@ -361,24 +358,20 @@ const DetailViewStackScreensStack = () => {
|
||||
<DetailViewStack.Screen
|
||||
name="ManageWallets"
|
||||
component={ManageWallets}
|
||||
options={navigationStyle({
|
||||
headerBackVisible: false,
|
||||
gestureEnabled: false,
|
||||
options={{
|
||||
presentation: 'fullScreenModal',
|
||||
title: loc.wallets.manage_title,
|
||||
statusBarStyle: 'auto',
|
||||
})(theme)}
|
||||
}}
|
||||
/>
|
||||
<DetailViewStack.Screen
|
||||
name="ScanQRCode"
|
||||
component={ScanQRCodeComponent}
|
||||
options={navigationStyle({
|
||||
options={{
|
||||
headerShown: false,
|
||||
statusBarHidden: true,
|
||||
autoHideHomeIndicator: true,
|
||||
presentation: 'fullScreenModal',
|
||||
headerShadowVisible: false,
|
||||
})(theme)}
|
||||
}}
|
||||
/>
|
||||
</DetailViewStack.Navigator>
|
||||
);
|
||||
|
||||
@ -16,6 +16,7 @@ export type ScanQRCodeParamList = {
|
||||
};
|
||||
|
||||
export type DetailViewStackParamList = {
|
||||
DrawerRoot: undefined;
|
||||
UnlockWithScreen: undefined;
|
||||
WalletsList: { onBarScanned?: string };
|
||||
WalletTransactions: { isLoading?: boolean; walletID: string; walletType: string; onBarScanned?: string };
|
||||
|
||||
8
navigation/DrawerParamList.ts
Normal file
8
navigation/DrawerParamList.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { DetailViewStackParamList } from './DetailViewStackParamList';
|
||||
|
||||
export type DrawerParamList = {
|
||||
DetailViewStackScreensStack: {
|
||||
screen?: keyof DetailViewStackParamList;
|
||||
params?: object;
|
||||
};
|
||||
};
|
||||
@ -1,5 +1,5 @@
|
||||
// DrawerRoot.tsx
|
||||
import { createDrawerNavigator, DrawerNavigationOptions } from '@react-navigation/drawer';
|
||||
import { createDrawerNavigator, DrawerNavigationOptions, DrawerContentComponentProps } from '@react-navigation/drawer';
|
||||
import React, { useLayoutEffect, useMemo } from 'react';
|
||||
import { I18nManager, LayoutAnimation } from 'react-native';
|
||||
|
||||
@ -7,10 +7,11 @@ import { useIsLargeScreen } from '../hooks/useIsLargeScreen';
|
||||
import DrawerList from '../screen/wallets/DrawerList';
|
||||
import DetailViewStackScreensStack from './DetailViewScreensStack';
|
||||
import { useSettings } from '../hooks/context/useSettings';
|
||||
import { DrawerParamList } from './DrawerParamList';
|
||||
|
||||
const Drawer = createDrawerNavigator();
|
||||
const Drawer = createDrawerNavigator<DrawerParamList>();
|
||||
|
||||
const DrawerListContent = (props: any) => {
|
||||
const DrawerContent = (props: DrawerContentComponentProps) => {
|
||||
return <DrawerList {...props} />;
|
||||
};
|
||||
|
||||
@ -21,8 +22,13 @@ const DrawerRoot = () => {
|
||||
const drawerStyle: DrawerNavigationOptions = useMemo(
|
||||
() => ({
|
||||
drawerPosition: I18nManager.isRTL ? 'right' : 'left',
|
||||
drawerStyle: { width: isLargeScreen && !isDrawerShouldHide ? 320 : '0%' },
|
||||
drawerType: isLargeScreen ? 'permanent' : 'back',
|
||||
drawerStyle: {
|
||||
width: isLargeScreen && !isDrawerShouldHide ? 320 : '0%',
|
||||
height: '100%',
|
||||
},
|
||||
drawerType: isLargeScreen ? 'permanent' : 'front',
|
||||
overlayColor: 'rgba(0,0,0,0.5)',
|
||||
swipeEnabled: !isDrawerShouldHide,
|
||||
}),
|
||||
[isDrawerShouldHide, isLargeScreen],
|
||||
);
|
||||
@ -32,7 +38,7 @@ const DrawerRoot = () => {
|
||||
}, [isDrawerShouldHide]);
|
||||
|
||||
return (
|
||||
<Drawer.Navigator screenOptions={drawerStyle} drawerContent={DrawerListContent}>
|
||||
<Drawer.Navigator screenOptions={drawerStyle} drawerContent={DrawerContent} initialRouteName="DetailViewStackScreensStack">
|
||||
<Drawer.Screen name="DetailViewStackScreensStack" component={DetailViewStackScreensStack} options={{ headerShown: false }} />
|
||||
</Drawer.Navigator>
|
||||
);
|
||||
|
||||
@ -4,9 +4,8 @@ import UnlockWith from '../screen/UnlockWith';
|
||||
import { LazyLoadingIndicator } from './LazyLoadingIndicator';
|
||||
import { DetailViewStackParamList } from './DetailViewStackParamList';
|
||||
import { useStorage } from '../hooks/context/useStorage';
|
||||
import { useIsLargeScreen } from '../hooks/useIsLargeScreen';
|
||||
import AddWalletStack from './AddWalletStack';
|
||||
|
||||
const DetailViewScreensStack = lazy(() => import('./DetailViewScreensStack'));
|
||||
const DrawerRoot = lazy(() => import('./DrawerRoot'));
|
||||
|
||||
export const NavigationDefaultOptions: NativeStackNavigationOptions = {
|
||||
@ -22,34 +21,29 @@ export const StatusBarLightOptions: NativeStackNavigationOptions = { statusBarSt
|
||||
|
||||
const DetailViewStack = createNativeStackNavigator<DetailViewStackParamList>();
|
||||
|
||||
const UnlockRoot = () => {
|
||||
const LazyDrawerRoot = () => (
|
||||
<Suspense fallback={<LazyLoadingIndicator />}>
|
||||
<DrawerRoot />
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
const MainRoot = () => {
|
||||
const { walletsInitialized } = useStorage();
|
||||
|
||||
return (
|
||||
<DetailViewStack.Navigator screenOptions={{ headerShown: false, animationTypeForReplace: 'push' }}>
|
||||
<DetailViewStack.Screen name="UnlockWithScreen" component={UnlockWith} />
|
||||
{!walletsInitialized ? (
|
||||
<DetailViewStack.Screen name="UnlockWithScreen" component={UnlockWith} />
|
||||
) : (
|
||||
<>
|
||||
<DetailViewStack.Screen name="DrawerRoot" component={LazyDrawerRoot} />
|
||||
|
||||
<DetailViewStack.Screen name="AddWalletRoot" component={AddWalletStack} options={NavigationDefaultOptions} />
|
||||
</>
|
||||
)}
|
||||
</DetailViewStack.Navigator>
|
||||
);
|
||||
};
|
||||
|
||||
const MainRoot = () => {
|
||||
const { walletsInitialized } = useStorage();
|
||||
const { isLargeScreen } = useIsLargeScreen();
|
||||
|
||||
const renderRoot = () => {
|
||||
if (!walletsInitialized) {
|
||||
return <UnlockRoot />;
|
||||
} else {
|
||||
// Conditional rendering based on the environment
|
||||
const Component = isLargeScreen ? DrawerRoot : DetailViewScreensStack;
|
||||
return (
|
||||
<Suspense fallback={<LazyLoadingIndicator />}>
|
||||
<Component />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return renderRoot();
|
||||
};
|
||||
|
||||
export default MainRoot;
|
||||
export { DetailViewStack }; // Exporting the navigator to use it in DetailViewScreensStack
|
||||
export { DetailViewStack };
|
||||
|
||||
@ -452,6 +452,10 @@ const ReceiveDetails = () => {
|
||||
return (
|
||||
<>
|
||||
<ScrollView
|
||||
automaticallyAdjustContentInsets
|
||||
contentInsetAdjustmentBehavior="automatic"
|
||||
automaticallyAdjustsScrollIndicatorInsets
|
||||
automaticallyAdjustKeyboardInsets
|
||||
testID="ReceiveDetailsScrollView"
|
||||
contentContainerStyle={[styles.root, stylesHook.root]}
|
||||
keyboardShouldPersistTaps="always"
|
||||
|
||||
@ -57,6 +57,7 @@ import ActionSheet from '../ActionSheet';
|
||||
import HeaderMenuButton from '../../components/HeaderMenuButton';
|
||||
import { CommonToolTipActions, ToolTipAction } from '../../typings/CommonToolTipActions';
|
||||
import { Action } from '../../components/types';
|
||||
import SafeArea from '../../components/SafeArea';
|
||||
|
||||
interface IPaymentDestinations {
|
||||
address: string; // btc address or payment code
|
||||
@ -1370,7 +1371,7 @@ const SendDetails = () => {
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={[styles.root, stylesHook.root]} onLayout={e => setWidth(e.nativeEvent.layout.width)}>
|
||||
<SafeArea style={[styles.root, stylesHook.root]} onLayout={e => setWidth(e.nativeEvent.layout.width)}>
|
||||
<View>
|
||||
<FlatList
|
||||
keyboardShouldPersistTaps="always"
|
||||
@ -1441,7 +1442,7 @@ const SendDetails = () => {
|
||||
})}
|
||||
|
||||
{renderWalletSelectionOrCoinsSelected()}
|
||||
</View>
|
||||
</SafeArea>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@ import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { AddWalletStackParamList } from '../../navigation/AddWalletStack';
|
||||
import { RouteProp, useRoute } from '@react-navigation/native';
|
||||
import SafeArea from '../../components/SafeArea';
|
||||
|
||||
enum ButtonSelected {
|
||||
// @ts-ignore: Return later to update
|
||||
@ -426,90 +427,92 @@ const WalletsAdd: React.FC = () => {
|
||||
automaticallyAdjustContentInsets
|
||||
automaticallyAdjustsScrollIndicatorInsets
|
||||
>
|
||||
<BlueSpacing20 />
|
||||
<BlueFormLabel>{loc.wallets.add_wallet_name}</BlueFormLabel>
|
||||
<View style={[styles.label, stylesHook.label]}>
|
||||
<TextInput
|
||||
testID="WalletNameInput"
|
||||
value={label}
|
||||
placeholderTextColor="#81868e"
|
||||
placeholder={loc.wallets.add_placeholder}
|
||||
onChangeText={setLabel}
|
||||
style={styles.textInputCommon}
|
||||
editable={!isLoading}
|
||||
underlineColorAndroid="transparent"
|
||||
/>
|
||||
</View>
|
||||
<BlueFormLabel>{loc.wallets.add_wallet_type}</BlueFormLabel>
|
||||
<View style={styles.buttons}>
|
||||
<WalletButton
|
||||
buttonType="Bitcoin"
|
||||
testID="ActivateBitcoinButton"
|
||||
active={selectedWalletType === ButtonSelected.ONCHAIN}
|
||||
onPress={handleOnBitcoinButtonPressed}
|
||||
size={styles.button}
|
||||
/>
|
||||
<WalletButton
|
||||
buttonType="Vault"
|
||||
testID="ActivateVaultButton"
|
||||
active={selectedWalletType === ButtonSelected.VAULT}
|
||||
onPress={handleOnVaultButtonPressed}
|
||||
size={styles.button}
|
||||
/>
|
||||
{selectedWalletType === ButtonSelected.OFFCHAIN && LightningButtonMemo}
|
||||
</View>
|
||||
<View style={styles.advanced}>
|
||||
{selectedWalletType === ButtonSelected.OFFCHAIN && (
|
||||
<>
|
||||
<BlueSpacing20 />
|
||||
<View style={styles.lndhubTitle}>
|
||||
<BlueText>{loc.wallets.add_lndhub}</BlueText>
|
||||
<BlueButtonLink title={loc.wallets.learn_more} onPress={onLearnMorePressed} />
|
||||
</View>
|
||||
|
||||
<View style={[styles.lndUri, stylesHook.lndUri]}>
|
||||
<TextInput
|
||||
value={walletBaseURI}
|
||||
onChangeText={setWalletBaseURI}
|
||||
onSubmitEditing={Keyboard.dismiss}
|
||||
placeholder={loc.wallets.add_lndhub_placeholder}
|
||||
clearButtonMode="while-editing"
|
||||
autoCapitalize="none"
|
||||
textContentType="URL"
|
||||
autoCorrect={false}
|
||||
placeholderTextColor="#81868e"
|
||||
style={styles.textInputCommon}
|
||||
editable={!isLoading}
|
||||
underlineColorAndroid="transparent"
|
||||
/>
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
|
||||
<SafeArea style={stylesHook.root}>
|
||||
<BlueSpacing20 />
|
||||
{!isLoading ? (
|
||||
<>
|
||||
<Button
|
||||
testID="Create"
|
||||
title={loc.wallets.add_create}
|
||||
disabled={
|
||||
!selectedWalletType || (selectedWalletType === ButtonSelected.OFFCHAIN && (walletBaseURI ?? '').trim().length === 0)
|
||||
}
|
||||
onPress={createWallet}
|
||||
/>
|
||||
<BlueFormLabel>{loc.wallets.add_wallet_name}</BlueFormLabel>
|
||||
<View style={[styles.label, stylesHook.label]}>
|
||||
<TextInput
|
||||
testID="WalletNameInput"
|
||||
value={label}
|
||||
placeholderTextColor="#81868e"
|
||||
placeholder={loc.wallets.add_placeholder}
|
||||
onChangeText={setLabel}
|
||||
style={styles.textInputCommon}
|
||||
editable={!isLoading}
|
||||
underlineColorAndroid="transparent"
|
||||
/>
|
||||
</View>
|
||||
<BlueFormLabel>{loc.wallets.add_wallet_type}</BlueFormLabel>
|
||||
<View style={styles.buttons}>
|
||||
<WalletButton
|
||||
buttonType="Bitcoin"
|
||||
testID="ActivateBitcoinButton"
|
||||
active={selectedWalletType === ButtonSelected.ONCHAIN}
|
||||
onPress={handleOnBitcoinButtonPressed}
|
||||
size={styles.button}
|
||||
/>
|
||||
<WalletButton
|
||||
buttonType="Vault"
|
||||
testID="ActivateVaultButton"
|
||||
active={selectedWalletType === ButtonSelected.VAULT}
|
||||
onPress={handleOnVaultButtonPressed}
|
||||
size={styles.button}
|
||||
/>
|
||||
{selectedWalletType === ButtonSelected.OFFCHAIN && LightningButtonMemo}
|
||||
</View>
|
||||
<View style={styles.advanced}>
|
||||
{selectedWalletType === ButtonSelected.OFFCHAIN && (
|
||||
<>
|
||||
<BlueSpacing20 />
|
||||
<View style={styles.lndhubTitle}>
|
||||
<BlueText>{loc.wallets.add_lndhub}</BlueText>
|
||||
<BlueButtonLink title={loc.wallets.learn_more} onPress={onLearnMorePressed} />
|
||||
</View>
|
||||
|
||||
<BlueButtonLink
|
||||
testID="ImportWallet"
|
||||
style={styles.import}
|
||||
title={loc.wallets.add_import_wallet}
|
||||
onPress={navigateToImportWallet}
|
||||
/>
|
||||
<BlueSpacing40 />
|
||||
</>
|
||||
) : (
|
||||
<ActivityIndicator />
|
||||
)}
|
||||
</View>
|
||||
<View style={[styles.lndUri, stylesHook.lndUri]}>
|
||||
<TextInput
|
||||
value={walletBaseURI}
|
||||
onChangeText={setWalletBaseURI}
|
||||
onSubmitEditing={Keyboard.dismiss}
|
||||
placeholder={loc.wallets.add_lndhub_placeholder}
|
||||
clearButtonMode="while-editing"
|
||||
autoCapitalize="none"
|
||||
textContentType="URL"
|
||||
autoCorrect={false}
|
||||
placeholderTextColor="#81868e"
|
||||
style={styles.textInputCommon}
|
||||
editable={!isLoading}
|
||||
underlineColorAndroid="transparent"
|
||||
/>
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
|
||||
<BlueSpacing20 />
|
||||
{!isLoading ? (
|
||||
<>
|
||||
<Button
|
||||
testID="Create"
|
||||
title={loc.wallets.add_create}
|
||||
disabled={
|
||||
!selectedWalletType || (selectedWalletType === ButtonSelected.OFFCHAIN && (walletBaseURI ?? '').trim().length === 0)
|
||||
}
|
||||
onPress={createWallet}
|
||||
/>
|
||||
|
||||
<BlueButtonLink
|
||||
testID="ImportWallet"
|
||||
style={styles.import}
|
||||
title={loc.wallets.add_import_wallet}
|
||||
onPress={navigateToImportWallet}
|
||||
/>
|
||||
<BlueSpacing40 />
|
||||
</>
|
||||
) : (
|
||||
<ActivityIndicator />
|
||||
)}
|
||||
</View>
|
||||
</SafeArea>
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { DrawerContentScrollView } from '@react-navigation/drawer';
|
||||
import { DrawerContentScrollView, DrawerContentComponentProps } from '@react-navigation/drawer';
|
||||
import { useIsFocused } from '@react-navigation/native';
|
||||
import React, { memo, useCallback, useEffect, useMemo, useReducer, useRef } from 'react';
|
||||
import { InteractionManager, LayoutAnimation, StyleSheet, View, ViewStyle } from 'react-native';
|
||||
@ -31,10 +31,6 @@ interface SelectWalletAction {
|
||||
walletType: string;
|
||||
}
|
||||
|
||||
interface SelectWalletAction {
|
||||
type: WalletActionType.SelectWallet;
|
||||
walletID: string;
|
||||
}
|
||||
interface NavigateAction {
|
||||
type: WalletActionType.Navigate;
|
||||
screen: string;
|
||||
@ -51,11 +47,6 @@ interface SetWalletsAction {
|
||||
wallets: TWallet[];
|
||||
}
|
||||
|
||||
interface SelectWalletAction {
|
||||
type: WalletActionType.SelectWallet;
|
||||
walletID: string;
|
||||
}
|
||||
|
||||
type WalletAction = SetWalletsAction | SelectWalletAction | SetFocusAction | NavigateAction;
|
||||
|
||||
const walletReducer = (state: WalletState, action: WalletAction): WalletState => {
|
||||
@ -74,16 +65,17 @@ const walletReducer = (state: WalletState, action: WalletAction): WalletState =>
|
||||
}
|
||||
};
|
||||
|
||||
const DrawerList: React.FC = memo(() => {
|
||||
const DrawerList: React.FC<DrawerContentComponentProps> = memo(props => {
|
||||
const initialState: WalletState = {
|
||||
wallets: [],
|
||||
isFocused: false,
|
||||
};
|
||||
|
||||
const navigation = useExtendedNavigation();
|
||||
const drawerNavigation = props.navigation;
|
||||
|
||||
const [state, dispatch] = useReducer(walletReducer, initialState);
|
||||
const walletsCarousel = useRef(null);
|
||||
const walletsCarousel = useRef<any>(null);
|
||||
const { wallets, selectedWalletID } = useStorage();
|
||||
const { colors } = useTheme();
|
||||
const isFocused = useIsFocused();
|
||||
@ -111,30 +103,42 @@ const DrawerList: React.FC = memo(() => {
|
||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
||||
dispatch({ type: WalletActionType.SelectWallet, walletID, walletType });
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
navigation.navigate({
|
||||
name: 'WalletTransactions',
|
||||
// Navigate to the nested screen through DetailViewStackScreensStack
|
||||
drawerNavigation.navigate('DetailViewStackScreensStack', {
|
||||
screen: 'WalletTransactions',
|
||||
params: { walletID, walletType },
|
||||
});
|
||||
// Close drawer after navigation
|
||||
drawerNavigation.closeDrawer();
|
||||
});
|
||||
}
|
||||
},
|
||||
[navigation],
|
||||
[drawerNavigation],
|
||||
);
|
||||
|
||||
const handleLongPress = useCallback(() => {
|
||||
if (state.wallets.length > 1) {
|
||||
navigation.navigate('ManageWallets');
|
||||
// Navigate to the nested screen through DetailViewStackScreensStack
|
||||
drawerNavigation.navigate('DetailViewStackScreensStack', {
|
||||
screen: 'ManageWallets',
|
||||
});
|
||||
drawerNavigation.closeDrawer();
|
||||
} else {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
||||
}
|
||||
}, [state.wallets.length, navigation]);
|
||||
}, [state.wallets.length, drawerNavigation]);
|
||||
|
||||
const onNewWalletPress = useCallback(() => {
|
||||
// Navigation needs to go through correct navigator hierarchy
|
||||
drawerNavigation.closeDrawer();
|
||||
|
||||
// This will reach the AddWalletRoot screen in DetailViewScreensStack
|
||||
navigation.navigate('AddWalletRoot');
|
||||
}, [navigation]);
|
||||
}, [navigation, drawerNavigation]);
|
||||
|
||||
return (
|
||||
<DrawerContentScrollView
|
||||
{...props}
|
||||
contentContainerStyle={stylesHook.root}
|
||||
contentInsetAdjustmentBehavior="automatic"
|
||||
automaticallyAdjustContentInsets={true}
|
||||
@ -155,7 +159,7 @@ const DrawerList: React.FC = memo(() => {
|
||||
ref={walletsCarousel}
|
||||
horizontal={false}
|
||||
isFlatList={false}
|
||||
onNewWalletPress={handleClick}
|
||||
onNewWalletPress={onNewWalletPress}
|
||||
testID="WalletsList"
|
||||
selectedWallet={selectedWalletID}
|
||||
scrollEnabled={state.isFocused}
|
||||
|
||||
@ -12,6 +12,7 @@ import { useStorage } from '../../hooks/context/useStorage';
|
||||
import { ExportMultisigCoordinationSetupStackRootParamList } from '../../navigation/ExportMultisigCoordinationSetupStack';
|
||||
import { useSettings } from '../../hooks/context/useSettings';
|
||||
import { enableScreenProtect, disableScreenProtect } from '../../helpers/screenProtect';
|
||||
import SafeArea from '../../components/SafeArea';
|
||||
|
||||
const enum ActionType {
|
||||
SET_LOADING = 'SET_LOADING',
|
||||
@ -161,7 +162,7 @@ const ExportMultisigCoordinationSetup: React.FC = () => {
|
||||
};
|
||||
|
||||
const renderView = wallet ? (
|
||||
<>
|
||||
<SafeArea style={[styles.scrollViewContent, stylesHook.scrollViewContent]}>
|
||||
<View>
|
||||
<BlueText style={[styles.type, stylesHook.type]}>{label}</BlueText>
|
||||
</View>
|
||||
@ -189,15 +190,16 @@ const ExportMultisigCoordinationSetup: React.FC = () => {
|
||||
<Text selectable style={[styles.secret, stylesHook.secret]}>
|
||||
{xpub}
|
||||
</Text>
|
||||
</>
|
||||
</SafeArea>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
style={stylesHook.scrollViewContent}
|
||||
contentContainerStyle={[styles.scrollViewContent, stylesHook.scrollViewContent]}
|
||||
centerContent
|
||||
automaticallyAdjustContentInsets
|
||||
automaticallyAdjustKeyboardInsets
|
||||
automaticallyAdjustsScrollIndicatorInsets
|
||||
contentInsetAdjustmentBehavior="automatic"
|
||||
>
|
||||
{isLoading ? <ActivityIndicator /> : renderView}
|
||||
|
||||
@ -14,7 +14,7 @@ import {
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
||||
import { useFocusEffect, usePreventRemove } from '@react-navigation/native';
|
||||
import { usePreventRemove } from '@react-navigation/native';
|
||||
import { useTheme } from '../../components/themes';
|
||||
import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
|
||||
import loc from '../../loc';
|
||||
@ -23,7 +23,6 @@ import { TTXMetadata } from '../../class';
|
||||
import { ExtendedTransaction, LightningTransaction, Transaction, TWallet } from '../../class/wallets/types';
|
||||
import useBounceAnimation from '../../hooks/useBounceAnimation';
|
||||
import HeaderRightButton from '../../components/HeaderRightButton';
|
||||
import { useSettings } from '../../hooks/context/useSettings';
|
||||
import DragList, { DragListRenderItemInfo } from 'react-native-draglist';
|
||||
import useDebounce from '../../hooks/useDebounce';
|
||||
|
||||
@ -203,7 +202,6 @@ if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental
|
||||
const ManageWallets: React.FC = () => {
|
||||
const { colors, closeImage } = useTheme();
|
||||
const { wallets: persistedWallets, setWalletsWithNewOrder, txMetadata, handleWalletDeletion } = useStorage();
|
||||
const { setIsDrawerShouldHide } = useSettings();
|
||||
const initialWalletsRef = useRef<TWallet[]>(deepCopyWallets(persistedWallets));
|
||||
const { navigate, setOptions, goBack, dispatch: navigationDispatch } = useExtendedNavigation();
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
@ -357,15 +355,6 @@ const ManageWallets: React.FC = () => {
|
||||
});
|
||||
}, [setOptions, HeaderLeftButton, SaveButton]);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
setIsDrawerShouldHide(true);
|
||||
return () => {
|
||||
setIsDrawerShouldHide(false);
|
||||
};
|
||||
}, [setIsDrawerShouldHide]),
|
||||
);
|
||||
|
||||
const renderHighlightedText = useCallback(
|
||||
(text: string, query: string) => {
|
||||
const parts = text.split(new RegExp(`(${query})`, 'gi'));
|
||||
|
||||
@ -102,7 +102,7 @@ const SelectWallet: React.FC = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.walletsCarousel}>
|
||||
<SafeArea style={styles.walletsCarousel}>
|
||||
<WalletsCarousel
|
||||
data={filteredWallets}
|
||||
scrollEnabled
|
||||
@ -111,7 +111,7 @@ const SelectWallet: React.FC = () => {
|
||||
testID="WalletsList"
|
||||
horizontal={false}
|
||||
/>
|
||||
</View>
|
||||
</SafeArea>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -44,6 +44,7 @@ import HeaderMenuButton from '../../components/HeaderMenuButton';
|
||||
import { Action } from '../../components/types';
|
||||
import { CommonToolTipActions } from '../../typings/CommonToolTipActions';
|
||||
import { popToTop } from '../../NavigationService';
|
||||
import SafeArea from '../../components/SafeArea';
|
||||
|
||||
type RouteProps = RouteProp<DetailViewStackParamList, 'WalletDetails'>;
|
||||
const WalletDetails: React.FC = () => {
|
||||
@ -426,6 +427,7 @@ const WalletDetails: React.FC = () => {
|
||||
return (
|
||||
<ScrollView
|
||||
automaticallyAdjustKeyboardInsets
|
||||
automaticallyAdjustsScrollIndicatorInsets
|
||||
contentInsetAdjustmentBehavior="automatic"
|
||||
automaticallyAdjustContentInsets
|
||||
centerContent={isLoading}
|
||||
@ -434,7 +436,7 @@ const WalletDetails: React.FC = () => {
|
||||
{isLoading ? (
|
||||
<BlueLoading />
|
||||
) : (
|
||||
<View>
|
||||
<SafeArea>
|
||||
<BlueCard style={styles.address}>
|
||||
{(() => {
|
||||
if (
|
||||
@ -665,7 +667,7 @@ const WalletDetails: React.FC = () => {
|
||||
<BlueSpacing20 />
|
||||
</View>
|
||||
</BlueCard>
|
||||
</View>
|
||||
</SafeArea>
|
||||
)}
|
||||
</ScrollView>
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user