diff --git a/components/Context/StorageProvider.tsx b/components/Context/StorageProvider.tsx index 08d0961da..b575797a7 100644 --- a/components/Context/StorageProvider.tsx +++ b/components/Context/StorageProvider.tsx @@ -458,7 +458,6 @@ export const StorageProvider = ({ children }: { children: React.ReactNode }) => refreshAllWalletTransactions, resetWallets, walletTransactionUpdateStatus, - setWalletTransactionUpdateStatus, handleWalletDeletion, ], ); diff --git a/components/WalletsCarousel.tsx b/components/WalletsCarousel.tsx index c2c712813..0b6ebbe00 100644 --- a/components/WalletsCarousel.tsx +++ b/components/WalletsCarousel.tsx @@ -98,8 +98,12 @@ interface WalletCarouselItemProps { isSelectedWallet?: boolean; customStyle?: ViewStyle; horizontal?: boolean; + isPlaceHolder?: boolean; searchQuery?: string; renderHighlightedText?: (text: string, query: string) => JSX.Element; + animationsEnabled?: boolean; + onPressIn?: () => void; + onPressOut?: () => void; } const iStyles = StyleSheet.create({ @@ -161,21 +165,6 @@ const iStyles = StyleSheet.create({ }, }); -interface WalletCarouselItemProps { - item: TWallet; - onPress: (item: TWallet) => void; - handleLongPress?: () => void; - isSelectedWallet?: boolean; - customStyle?: ViewStyle; - horizontal?: boolean; - isPlaceHolder?: boolean; - searchQuery?: string; - renderHighlightedText?: (text: string, query: string) => JSX.Element; - animationsEnabled?: boolean; - onPressIn?: () => void; - onPressOut?: () => void; -} - export const WalletCarouselItem: React.FC = React.memo( ({ item, @@ -203,7 +192,6 @@ export const WalletCarouselItem: React.FC = React.memo( Animated.spring(scaleValue, { toValue: 0.95, useNativeDriver: true, - friction: 3, tension: 100, }).start(); } @@ -215,7 +203,6 @@ export const WalletCarouselItem: React.FC = React.memo( Animated.spring(scaleValue, { toValue: 1.0, useNativeDriver: true, - friction: 3, tension: 100, }).start(); } @@ -362,6 +349,10 @@ const WalletsCarousel = forwardRef((props renderHighlightedText, isFlatList = true, } = props; + + const { width } = useWindowDimensions(); + const itemWidth = React.useMemo(() => (width * 0.82 > 375 ? 375 : width * 0.82), [width]); + const renderItem = useCallback( ({ item, index }: ListRenderItemInfo) => item ? ( @@ -379,7 +370,6 @@ const WalletsCarousel = forwardRef((props ); const flatListRef = useRef>(null); - useImperativeHandle(ref, (): any => { return { scrollToEnd: (params: { animated?: boolean | null | undefined } | undefined) => flatListRef.current?.scrollToEnd(params), @@ -401,10 +391,8 @@ const WalletsCarousel = forwardRef((props getNativeScrollRef: () => flatListRef.current?.getNativeScrollRef(), }; }, []); - const onScrollToIndexFailed = (error: { averageItemLength: number; index: number }): void => { - console.debug('onScrollToIndexFailed'); - console.debug(error); + console.debug('onScrollToIndexFailed', error); flatListRef.current?.scrollToOffset({ offset: error.averageItemLength * error.index, animated: true }); setTimeout(() => { if (data.length !== 0 && flatListRef.current !== null) { @@ -413,16 +401,16 @@ const WalletsCarousel = forwardRef((props }, 100); }; - const { width } = useWindowDimensions(); const sliderHeight = 195; - const itemWidth = width * 0.82 > 375 ? 375 : width * 0.82; + + const keyExtractor = useCallback((item: TWallet, index: number) => (item?.getID ? item.getID() : index.toString()), []); return isFlatList ? ( index.toString()} + keyExtractor={keyExtractor} showsVerticalScrollIndicator={false} pagingEnabled={horizontal} disableIntervalMomentum={horizontal} diff --git a/components/navigationStyle.tsx b/components/navigationStyle.tsx index 3e7d624a5..ceaf60bf4 100644 --- a/components/navigationStyle.tsx +++ b/components/navigationStyle.tsx @@ -59,7 +59,6 @@ const navigationStyle = ( { closeButtonPosition, onCloseButtonPressed, - headerBackVisible = Platform.OS === 'ios' || !closeButtonPosition, ...opts }: NativeStackNavigationOptions & { closeButtonPosition?: CloseButtonPosition; @@ -103,19 +102,24 @@ const navigationStyle = ( ); } - - let options: NativeStackNavigationOptions = { + const baseHeaderStyle = { headerShadowVisible: false, headerTitleStyle: { - fontWeight: '600', + fontWeight: '600' as const, color: theme.colors.foregroundColor, }, - headerBackVisible, - headerBackTitle: undefined, - headerBackButtonDisplayMode: 'minimal', headerTintColor: theme.colors.foregroundColor, + headerBackButtonDisplayMode: 'minimal', + }; + const isLeftCloseButtonAndroid = closeButton === CloseButtonPosition.Left && Platform.OS === 'android'; + + const leftCloseButtonStyle = isLeftCloseButtonAndroid ? { headerBackImageSource: theme.closeImage } : { headerLeft }; + + let options: NativeStackNavigationOptions = { + ...baseHeaderStyle, + ...leftCloseButtonStyle, + headerBackButtonDisplayMode: 'minimal', headerRight, - headerLeft, ...opts, }; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 454254ff9..e848c7b66 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1819,7 +1819,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - RNScreens (4.6.0): + - RNScreens (4.7.0): - DoubleConversion - glog - hermes-engine @@ -2312,7 +2312,7 @@ SPEC CHECKSUMS: RNRate: 7641919330e0d6688ad885a985b4bd697ed7d14c RNReactNativeHapticFeedback: 00ba111b82aa266bb3ee1aa576831c2ea9a9dfad RNReanimated: 66cf0f600a26d2b5e74c6e0b1c77c1ab1f62fc05 - RNScreens: b05d3b8e716e68d9e2f1364d440d23de5b6885f1 + RNScreens: 9a7346d6ce564a948e9d61cf9ec10950093e34df RNShare: 6204e6a1987ba3e7c47071ef703e5449a0e3548a RNSVG: 86fecdfc637614ba9def63f7f3f2e7795e018356 RNVectorIcons: 182892e7d1a2f27b52d3c627eca5d2665a22ee28 diff --git a/navigation/DetailViewScreensStack.tsx b/navigation/DetailViewScreensStack.tsx index fc63e63be..affe7cc19 100644 --- a/navigation/DetailViewScreensStack.tsx +++ b/navigation/DetailViewScreensStack.tsx @@ -375,6 +375,7 @@ const DetailViewStackScreensStack = () => { options={navigationStyle({ headerShown: false, statusBarHidden: true, + autoHideHomeIndicator: true, presentation: 'fullScreenModal', headerShadowVisible: false, })(theme)} diff --git a/navigation/ReceiveDetailsStack.tsx b/navigation/ReceiveDetailsStack.tsx index a18377e49..6b7cda2a1 100644 --- a/navigation/ReceiveDetailsStack.tsx +++ b/navigation/ReceiveDetailsStack.tsx @@ -1,7 +1,6 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack'; import React from 'react'; - -import navigationStyle from '../components/navigationStyle'; +import navigationStyle, { CloseButtonPosition } from '../components/navigationStyle'; import { useTheme } from '../components/themes'; import loc from '../loc'; import { ReceiveDetailsComponent } from './LazyLoadReceiveDetailsStack'; @@ -16,7 +15,11 @@ const ReceiveDetailsStackRoot = () => { ); diff --git a/package-lock.json b/package-lock.json index 8b63619f2..7ff735817 100644 --- a/package-lock.json +++ b/package-lock.json @@ -91,7 +91,7 @@ "react-native-reanimated": "3.16.7", "react-native-safe-area-context": "5.2.0", "react-native-screen-capture": "github:BlueWallet/react-native-screen-capture#18cb79f", - "react-native-screens": "4.6.0", + "react-native-screens": "4.7.0", "react-native-secure-key-store": "github:BlueWallet/react-native-secure-key-store#2076b4849e88aa0a78e08bfbb4ce3923e0925cbc", "react-native-share": "11.1.0", "react-native-svg": "15.11.1", @@ -22102,9 +22102,9 @@ } }, "node_modules/react-native-screens": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.6.0.tgz", - "integrity": "sha512-PqGtR/moJLiTMSavhfo5spKXNHZrlxffq3g5UUVPmyuu7MmazFlPvYqiAYnR2iB9tkJYgvZO6sbjYAE7619M0A==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.7.0.tgz", + "integrity": "sha512-PKBwBIKasBuaR6otU7GsUb9t5pb2eG1G9uHMHOivst/Iw1tXK+DDz1HSDQFjwcj2pUjrKSkXmwUtbY/oAvsCUA==", "license": "MIT", "dependencies": { "react-freeze": "^1.0.0", diff --git a/package.json b/package.json index cde3717b8..6edc0fd71 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@react-navigation/devtools": "7.0.15", "@react-native/metro-babel-transformer": "^0.76.7", "@react-native/typescript-config": "0.76.7", + "@react-navigation/devtools": "7.0.15", "@testing-library/react-native": "^13.0.1", "@types/bip38": "^3.1.2", "@types/bs58check": "^2.1.0", @@ -160,7 +161,7 @@ "react-native-reanimated": "3.16.7", "react-native-safe-area-context": "5.2.0", "react-native-screen-capture": "github:BlueWallet/react-native-screen-capture#18cb79f", - "react-native-screens": "4.6.0", + "react-native-screens": "4.7.0", "react-native-secure-key-store": "github:BlueWallet/react-native-secure-key-store#2076b4849e88aa0a78e08bfbb4ce3923e0925cbc", "react-native-share": "11.1.0", "react-native-svg": "15.11.1", diff --git a/screen/receive/details.js b/screen/receive/details.js index 9830a32b2..efdf5fbf0 100644 --- a/screen/receive/details.js +++ b/screen/receive/details.js @@ -1,17 +1,6 @@ import { useFocusEffect, useRoute } from '@react-navigation/native'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { - BackHandler, - Image, - InteractionManager, - LayoutAnimation, - ScrollView, - StyleSheet, - Text, - TextInput, - TouchableOpacity, - View, -} from 'react-native'; +import { BackHandler, InteractionManager, LayoutAnimation, ScrollView, StyleSheet, Text, TextInput, View } from 'react-native'; import Share from 'react-native-share'; import * as BlueElectrum from '../../blue_modules/BlueElectrum'; @@ -92,7 +81,7 @@ const ReceiveDetails = () => { const [currentTab, setCurrentTab] = useState(segmentControlValues[0]); const { goBack, setParams, setOptions } = useExtendedNavigation(); const bottomModalRef = useRef(null); - const { colors, closeImage } = useTheme(); + const { colors } = useTheme(); const [intervalMs, setIntervalMs] = useState(5000); const [eta, setEta] = useState(''); const [initialConfirmed, setInitialConfirmed] = useState(0); @@ -212,32 +201,12 @@ const ReceiveDetails = () => { [onPressMenuItem, toolTipActions], ); - const handleClose = useCallback(() => { - goBack(); - }, [goBack]); - - const HeaderLeft = useMemo( - () => ( - - - - ), - [closeImage, handleClose], - ); - useEffect(() => { wallet?.allowBIP47() && setOptions({ - headerLeft: () => HeaderLeft, headerRight: () => HeaderRight, }); - }, [HeaderLeft, HeaderRight, colors.foregroundColor, setOptions, wallet]); + }, [HeaderRight, colors.foregroundColor, setOptions, wallet]); // re-fetching address balance periodically useEffect(() => { diff --git a/screen/send/ScanQRCode.js b/screen/send/ScanQRCode.js index 70189b0d1..b151be280 100644 --- a/screen/send/ScanQRCode.js +++ b/screen/send/ScanQRCode.js @@ -29,6 +29,7 @@ const styles = StyleSheet.create({ justifyContent: 'center', alignContent: 'center', alignItems: 'center', + height: '100%', }, backdoorButton: { width: 60, @@ -70,7 +71,7 @@ const ScanQRCode = () => { const [backdoorText, setBackdoorText] = useState(''); const [backdoorVisible, setBackdoorVisible] = useState(false); const [animatedQRCodeData, setAnimatedQRCodeData] = useState({}); - const [cameraStatusGranted, setCameraStatusGranted] = useState(false); + const [cameraStatusGranted, setCameraStatusGranted] = useState(undefined); const stylesHook = StyleSheet.create({ openSettingsContainer: { backgroundColor: colors.brandingColor, @@ -280,7 +281,7 @@ const ScanQRCode = () => { ) : ( - {!cameraStatusGranted ? ( + {cameraStatusGranted === false ? ( {loc.send.permission_camera_message} @@ -292,7 +293,7 @@ const ScanQRCode = () => {