Merge branch 'master' into Carousel-on-the-main-screen-does-not-working-from-the-first-go

This commit is contained in:
Marcos Rodriguez Velez 2025-02-24 21:34:56 -04:00
commit c008a644cc
10 changed files with 59 additions and 76 deletions

View file

@ -1,5 +1,6 @@
import { Platform } from 'react-native';
import { check, request, PERMISSIONS, RESULTS } from 'react-native-permissions';
import { navigationRef } from '../NavigationService.ts';
const isCameraAuthorizationStatusGranted = async () => {
const status = await check(Platform.OS === 'android' ? PERMISSIONS.ANDROID.CAMERA : PERMISSIONS.IOS.CAMERA);
@ -10,4 +11,16 @@ const requestCameraAuthorization = () => {
return request(Platform.OS === 'android' ? PERMISSIONS.ANDROID.CAMERA : PERMISSIONS.IOS.CAMERA);
};
export { isCameraAuthorizationStatusGranted, requestCameraAuthorization };
const scanQrHelper = (): Promise<string> => {
return new Promise(resolve => {
if (navigationRef.isReady()) {
navigationRef.current?.navigate('ScanQRCode', {
onBarScanned: (data: string) => {
resolve(data);
},
});
}
});
};
export { isCameraAuthorizationStatusGranted, requestCameraAuthorization, scanQrHelper };

View file

@ -55,9 +55,13 @@ const useHandoffListener = () => {
const activitySubscription = eventEmitter?.addListener('onUserActivityOpen', handleUserActivity);
EventEmitter.getMostRecentUserActivity?.()
.then(handleUserActivity)
.catch(() => console.debug('No valid user activity object received'));
if (EventEmitter && EventEmitter.getMostRecentUserActivity) {
EventEmitter.getMostRecentUserActivity()
.then(handleUserActivity)
.catch(() => console.debug('No valid user activity object received'));
} else {
console.debug('EventEmitter native module is not available.');
}
return () => {
activitySubscription?.remove();

View file

@ -17,6 +17,7 @@ LogBox.ignoreLogs([
'Require cycle:',
'Battery state `unknown` and monitoring disabled, this is normal for simulators and tvOS.',
'Open debugger to view warnings.',
'Non-serializable values were found in the navigation state',
]);
const BlueAppComponent = () => {

View file

@ -1819,7 +1819,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNScreens (4.7.0):
- RNScreens (4.9.0):
- DoubleConversion
- glog
- hermes-engine
@ -2312,7 +2312,7 @@ SPEC CHECKSUMS:
RNRate: 7641919330e0d6688ad885a985b4bd697ed7d14c
RNReactNativeHapticFeedback: 00ba111b82aa266bb3ee1aa576831c2ea9a9dfad
RNReanimated: 66cf0f600a26d2b5e74c6e0b1c77c1ab1f62fc05
RNScreens: 9a7346d6ce564a948e9d61cf9ec10950093e34df
RNScreens: ee069f569efb54804334321c916643f8cc9debaf
RNShare: 6204e6a1987ba3e7c47071ef703e5449a0e3548a
RNSVG: 86fecdfc637614ba9def63f7f3f2e7795e018356
RNVectorIcons: 182892e7d1a2f27b52d3c627eca5d2665a22ee28

View file

@ -32,8 +32,8 @@ export type DetailViewStackParamList = {
LNDViewInvoice: { invoice: LightningTransaction; walletID: string };
LNDViewAdditionalInvoiceInformation: { invoiceId: string };
LNDViewAdditionalInvoicePreImage: { invoiceId: string };
Broadcast: { onBarScanned?: string };
IsItMyAddress: { address?: string; onBarScanned?: string };
Broadcast: object;
IsItMyAddress: object;
GenerateWord: undefined;
LnurlPay: undefined;
LnurlPaySuccess: {

8
package-lock.json generated
View file

@ -92,7 +92,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.7.0",
"react-native-screens": "4.9.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",
@ -22101,9 +22101,9 @@
}
},
"node_modules/react-native-screens": {
"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==",
"version": "4.9.0",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.9.0.tgz",
"integrity": "sha512-Pp+Jl3Hzon6oCAUzIP3HxK1TabMTRcTZB+3LKdA8ZQtHolAJdHJWJgNyN6GBG41vXRBnSkXgcvUUbHmMCCNpNQ==",
"license": "MIT",
"dependencies": {
"react-freeze": "^1.0.0",

View file

@ -160,7 +160,7 @@
"@react-navigation/devtools": "7.0.15",
"react-native-safe-area-context": "5.2.0",
"react-native-screen-capture": "github:BlueWallet/react-native-screen-capture#18cb79f",
"react-native-screens": "4.7.0",
"react-native-screens": "4.9.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",

View file

@ -1,5 +1,4 @@
import React, { useState, useEffect, useCallback } from 'react';
import { useRoute, RouteProp } from '@react-navigation/native';
import React, { useCallback, useState } from 'react';
import * as bitcoin from 'bitcoinjs-lib';
import { ActivityIndicator, Keyboard, Linking, StyleSheet, TextInput, View } from 'react-native';
@ -20,11 +19,9 @@ import Button from '../../components/Button';
import SafeArea from '../../components/SafeArea';
import { useTheme } from '../../components/themes';
import loc from '../../loc';
import { DetailViewStackParamList } from '../../navigation/DetailViewStackParamList';
import { useSettings } from '../../hooks/context/useSettings';
import { majorTomToGroundControl } from '../../blue_modules/notifications';
import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { scanQrHelper } from '../../helpers/scan-qr.ts';
const BROADCAST_RESULT = Object.freeze({
none: 'Input transaction hex',
@ -33,17 +30,12 @@ const BROADCAST_RESULT = Object.freeze({
error: 'error',
});
type RouteProps = RouteProp<DetailViewStackParamList, 'Broadcast'>;
type NavigationProps = NativeStackNavigationProp<DetailViewStackParamList, 'Broadcast'>;
const Broadcast: React.FC = () => {
const { params } = useRoute<RouteProps>();
const [tx, setTx] = useState<string | undefined>();
const [txHex, setTxHex] = useState<string | undefined>();
const { colors } = useTheme();
const [broadcastResult, setBroadcastResult] = useState<string>(BROADCAST_RESULT.none);
const { selectedBlockExplorer } = useSettings();
const { setParams, navigate } = useExtendedNavigation<NavigationProps>();
const stylesHooks = StyleSheet.create({
input: {
@ -66,14 +58,6 @@ const Broadcast: React.FC = () => {
} catch (e) {}
}, []);
useEffect(() => {
const scannedData = params?.onBarScanned;
if (scannedData) {
handleScannedData(scannedData);
setParams({ onBarScanned: undefined });
}
}, [handleScannedData, params?.onBarScanned, setParams]);
const handleUpdateTxHex = (nextValue: string) => setTxHex(nextValue.trim());
const handleBroadcast = async () => {
@ -104,10 +88,11 @@ const Broadcast: React.FC = () => {
}
};
const handleQRScan = () => {
navigate('ScanQRCode', {
showFileImportButton: true,
});
const handleQRScan = async () => {
const scannedData = await scanQrHelper();
if (scannedData) {
handleScannedData(scannedData);
}
};
let status;

View file

@ -64,7 +64,7 @@ const ScanQRCode = () => {
const previousRoute = navigationState.routes[navigationState.routes.length - 2];
const defaultLaunchedBy = previousRoute ? previousRoute.name : undefined;
const { launchedBy = defaultLaunchedBy, showFileImportButton } = route.params || {};
const { launchedBy = defaultLaunchedBy, showFileImportButton, onBarScanned } = route.params || {};
const scannedCache: Record<string, number> = {};
const { colors } = useTheme();
const isFocused = useIsFocused();
@ -116,6 +116,9 @@ const ScanQRCode = () => {
if (launchedBy) {
const merge = true;
const popToAction = StackActions.popTo(launchedBy, { onBarScanned: data }, merge);
if (onBarScanned) {
onBarScanned(data);
}
navigation.dispatch(popToAction);
}
@ -156,6 +159,9 @@ const ScanQRCode = () => {
if (launchedBy) {
const merge = true;
const popToAction = StackActions.popTo(launchedBy, { onBarScanned: data }, merge);
if (onBarScanned) {
onBarScanned(data);
}
navigation.dispatch(popToAction);
}
@ -212,6 +218,9 @@ const ScanQRCode = () => {
if (launchedBy) {
const merge = true;
const popToAction = StackActions.popTo(launchedBy, { onBarScanned: data }, merge);
if (onBarScanned) {
onBarScanned(data);
}
navigation.dispatch(popToAction);
}
return;
@ -222,6 +231,9 @@ const ScanQRCode = () => {
const merge = true;
const popToAction = StackActions.popTo(launchedBy, { onBarScanned: ret.data }, merge);
if (onBarScanned) {
onBarScanned(ret.data);
}
navigation.dispatch(popToAction);
} catch (e) {

View file

@ -1,5 +1,4 @@
import React, { useRef, useState, useEffect } from 'react';
import { useRoute, useNavigation, RouteProp } from '@react-navigation/native';
import { Keyboard, StyleSheet, TextInput, View, ScrollView, TouchableOpacity, Text } from 'react-native';
import { BlueButtonLink, BlueCard, BlueSpacing10, BlueSpacing20, BlueSpacing40, BlueText } from '../../BlueComponents';
import Button from '../../components/Button';
@ -8,23 +7,17 @@ import loc from '../../loc';
import { useStorage } from '../../hooks/context/useStorage';
import { TWallet } from '../../class/wallets/types';
import { WalletCarouselItem } from '../../components/WalletsCarousel';
import { DetailViewStackParamList } from '../../navigation/DetailViewStackParamList';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import Icon from 'react-native-vector-icons/MaterialIcons';
import { Divider } from '@rneui/themed';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
import presentAlert from '../../components/Alert';
import { navigate } from '../../NavigationService';
type RouteProps = RouteProp<DetailViewStackParamList, 'IsItMyAddress'>;
type NavigationProp = NativeStackNavigationProp<DetailViewStackParamList, 'IsItMyAddress'>;
import { scanQrHelper } from '../../helpers/scan-qr.ts';
import { useExtendedNavigation } from '../../hooks/useExtendedNavigation.ts';
const IsItMyAddress: React.FC = () => {
const { navigate } = useExtendedNavigation();
const { wallets } = useStorage();
const navigation = useNavigation<NavigationProp>();
const route = useRoute<RouteProps>();
const { colors } = useTheme();
const scanButtonRef = useRef<any>();
const scrollViewRef = useRef<ScrollView>(null);
const firstWalletRef = useRef<View>(null);
@ -40,20 +33,6 @@ const IsItMyAddress: React.FC = () => {
},
});
useEffect(() => {
if (route.params?.address && route.params.address !== address) {
setAddress(route.params.address);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [route.params?.address]);
useEffect(() => {
const currentAddress = route.params?.address;
if (currentAddress !== address) {
navigation.setParams({ address });
}
}, [address, navigation, route.params?.address]);
const handleUpdateAddress = (nextValue: string) => setAddress(nextValue);
const clearAddressInput = () => {
@ -102,27 +81,16 @@ const IsItMyAddress: React.FC = () => {
}
};
const onBarScanned = (value: string) => {
const importScan = async () => {
const value = await scanQrHelper();
const cleanAddress = value.replace(/^bitcoin(:|=)/i, '').split('?')[0];
setAddress(value);
setResultCleanAddress(cleanAddress);
};
const importScan = async () => {
navigate('ScanQRCode');
};
useEffect(() => {
const data = route.params?.onBarScanned;
if (data) {
onBarScanned(data);
navigation.setParams({ onBarScanned: undefined });
}
}, [navigation, route.name, route.params?.onBarScanned]);
const viewQRCode = () => {
if (!resultCleanAddress) return;
navigation.navigate('ReceiveDetailsRoot', {
navigate('ReceiveDetailsRoot', {
screen: 'ReceiveDetails',
params: {
address: resultCleanAddress,
@ -195,7 +163,7 @@ const IsItMyAddress: React.FC = () => {
</View>
<BlueSpacing10 />
<BlueButtonLink ref={scanButtonRef} title={loc.wallets.import_scan_qr} onPress={importScan} />
<BlueButtonLink title={loc.wallets.import_scan_qr} onPress={importScan} />
<BlueSpacing20 />
{resultCleanAddress && (
<>
@ -227,7 +195,7 @@ const IsItMyAddress: React.FC = () => {
<WalletCarouselItem
item={wallet}
onPress={item => {
navigation.navigate('WalletTransactions', {
navigate('WalletTransactions', {
walletID: item.getID(),
walletType: item.type,
});