mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-01-19 05:45:15 +01:00
Merge branch 'master' into modal
This commit is contained in:
commit
a544f5c324
@ -288,7 +288,6 @@ interface WalletsCarouselProps extends Partial<FlatListProps<any>> {
|
||||
handleLongPress?: () => void;
|
||||
data: TWallet[];
|
||||
scrollEnabled?: boolean;
|
||||
showNewWalletPanel?: boolean; // New prop
|
||||
}
|
||||
|
||||
type FlatListRefType = FlatList<any> & {
|
||||
@ -317,7 +316,7 @@ const cStyles = StyleSheet.create({
|
||||
const ListHeaderComponent: React.FC = () => <View style={cStyles.separatorStyle} />;
|
||||
|
||||
const WalletsCarousel = forwardRef<FlatListRefType, WalletsCarouselProps>((props, ref) => {
|
||||
const { horizontal, data, handleLongPress, onPress, selectedWallet, scrollEnabled, showNewWalletPanel, onNewWalletPress } = props;
|
||||
const { horizontal, data, handleLongPress, onPress, selectedWallet, scrollEnabled, onNewWalletPress } = props;
|
||||
const renderItem = useCallback(
|
||||
({ item, index }: ListRenderItemInfo<TWallet>) =>
|
||||
item ? (
|
||||
@ -357,8 +356,8 @@ const WalletsCarousel = forwardRef<FlatListRefType, WalletsCarouselProps>((props
|
||||
}, []);
|
||||
|
||||
const onScrollToIndexFailed = (error: { averageItemLength: number; index: number }): void => {
|
||||
console.log('onScrollToIndexFailed');
|
||||
console.log(error);
|
||||
console.debug('onScrollToIndexFailed');
|
||||
console.debug(error);
|
||||
flatListRef.current?.scrollToOffset({ offset: error.averageItemLength * error.index, animated: true });
|
||||
setTimeout(() => {
|
||||
if (data.length !== 0 && flatListRef.current !== null) {
|
||||
@ -390,7 +389,7 @@ const WalletsCarousel = forwardRef<FlatListRefType, WalletsCarouselProps>((props
|
||||
ListHeaderComponent={ListHeaderComponent}
|
||||
style={{ minHeight: sliderHeight + 12 }}
|
||||
onScrollToIndexFailed={onScrollToIndexFailed}
|
||||
ListFooterComponent={showNewWalletPanel && onNewWalletPress ? <NewWalletPanel onPress={onNewWalletPress} /> : null}
|
||||
ListFooterComponent={onNewWalletPress ? <NewWalletPanel onPress={onNewWalletPress} /> : null}
|
||||
{...props}
|
||||
/>
|
||||
) : (
|
||||
@ -406,7 +405,7 @@ const WalletsCarousel = forwardRef<FlatListRefType, WalletsCarouselProps>((props
|
||||
/>
|
||||
) : null,
|
||||
)}
|
||||
{showNewWalletPanel && onNewWalletPress && <NewWalletPanel onPress={onNewWalletPress} />}
|
||||
{onNewWalletPress && <NewWalletPanel onPress={onNewWalletPress} />}
|
||||
</View>
|
||||
);
|
||||
});
|
||||
|
@ -10,53 +10,42 @@ import { navigationRef } from '../NavigationService';
|
||||
* @param showFileImportButton {boolean}
|
||||
*
|
||||
* @param onDismiss {function} - if camera is closed via X button it gets triggered
|
||||
* @param options {object} - additional options to pass to navigate
|
||||
* @return {Promise<string | null>}
|
||||
* @param useMerge {boolean} - if true, will merge the new screen with the current screen, otherwise will replace the current screen
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
function scanQrHelper(
|
||||
currentScreenName: string,
|
||||
showFileImportButton = true,
|
||||
onDismiss?: () => void,
|
||||
options: { merge: boolean } = { merge: true },
|
||||
useMerge = true,
|
||||
): Promise<string | null> {
|
||||
return requestCameraAuthorization().then(() => {
|
||||
return new Promise(resolve => {
|
||||
const params: any = {
|
||||
showFileImportButton: Boolean(showFileImportButton),
|
||||
};
|
||||
let params = {};
|
||||
|
||||
if (options?.merge) {
|
||||
if (onDismiss) {
|
||||
params.onDismiss = onDismiss;
|
||||
}
|
||||
params.onBarScanned = function (data: any) {
|
||||
if (useMerge) {
|
||||
const onBarScanned = function (data: any) {
|
||||
setTimeout(() => resolve(data.data || data), 1);
|
||||
navigationRef.navigate({
|
||||
name: currentScreenName,
|
||||
params: {},
|
||||
merge: options?.merge,
|
||||
});
|
||||
navigationRef.navigate({ name: currentScreenName, params: {}, merge: true });
|
||||
};
|
||||
|
||||
navigationRef.navigate({
|
||||
name: 'ScanQRCodeRoot',
|
||||
params: {
|
||||
screen: 'ScanQRCode',
|
||||
params,
|
||||
},
|
||||
merge: true,
|
||||
});
|
||||
params = {
|
||||
showFileImportButton: Boolean(showFileImportButton),
|
||||
onDismiss,
|
||||
onBarScanned,
|
||||
};
|
||||
} else {
|
||||
navigationRef.navigate({
|
||||
name: 'ScanQRCodeRoot',
|
||||
params: {
|
||||
screen: 'ScanQRCode',
|
||||
params: {
|
||||
showFileImportButton: Boolean(showFileImportButton),
|
||||
},
|
||||
},
|
||||
});
|
||||
params = { launchedBy: currentScreenName, showFileImportButton: Boolean(showFileImportButton) };
|
||||
}
|
||||
|
||||
navigationRef.navigate({
|
||||
name: 'ScanQRCodeRoot',
|
||||
params: {
|
||||
screen: 'ScanQRCode',
|
||||
params,
|
||||
},
|
||||
merge: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
{
|
||||
"originHash" : "52530e6b1e3a85c8854952ef703a6d1bbe1acd82713be2b3166476b9b277db23",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "bugsnag-cocoa",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/bugsnag/bugsnag-cocoa",
|
||||
"state" : {
|
||||
"revision" : "16b9145fc66e5296f16e733f6feb5d0e450574e8",
|
||||
"version" : "6.28.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "efqrcode",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/EFPrefix/EFQRCode.git",
|
||||
"state" : {
|
||||
"revision" : "2991c2f318ad9529d93b2a73a382a3f9c72c64ce",
|
||||
"version" : "6.2.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "keychain-swift",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/evgenyneu/keychain-swift.git",
|
||||
"state" : {
|
||||
"revision" : "5e1b02b6a9dac2a759a1d5dbc175c86bd192a608",
|
||||
"version" : "24.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift_qrcodejs",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/ApolloZhu/swift_qrcodejs.git",
|
||||
"state" : {
|
||||
"revision" : "374dc7f7b9e76c6aeb393f6a84590c6d387e1ecb",
|
||||
"version" : "2.2.2"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 3
|
||||
}
|
@ -865,4 +865,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: f19eea438501edfe85fb2fa51d40ba1b57540758
|
||||
|
||||
COCOAPODS: 1.15.2
|
||||
COCOAPODS: 1.14.3
|
||||
|
@ -3,7 +3,7 @@ import { SendDetailsParams } from './SendDetailsStackParamList';
|
||||
|
||||
export type DetailViewStackParamList = {
|
||||
UnlockWithScreen: undefined;
|
||||
WalletsList: undefined;
|
||||
WalletsList: { scannedData?: string };
|
||||
WalletTransactions: { walletID: string; walletType: string };
|
||||
LDKOpenChannelRoot: undefined;
|
||||
LdkInfo: undefined;
|
||||
@ -18,7 +18,7 @@ export type DetailViewStackParamList = {
|
||||
LNDViewInvoice: { invoice: LightningTransaction; walletID: string };
|
||||
LNDViewAdditionalInvoiceInformation: { invoiceId: string };
|
||||
LNDViewAdditionalInvoicePreImage: { invoiceId: string };
|
||||
Broadcast: undefined;
|
||||
Broadcast: { scannedData?: string };
|
||||
IsItMyAddress: undefined;
|
||||
GenerateWord: undefined;
|
||||
LnurlPay: undefined;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useRoute } from '@react-navigation/native';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useRoute, RouteProp } from '@react-navigation/native';
|
||||
import * as bitcoin from 'bitcoinjs-lib';
|
||||
import { ActivityIndicator, Keyboard, KeyboardAvoidingView, Linking, Platform, StyleSheet, TextInput, View } from 'react-native';
|
||||
|
||||
@ -23,6 +23,7 @@ import SafeArea from '../../components/SafeArea';
|
||||
import { useTheme } from '../../components/themes';
|
||||
import { scanQrHelper } from '../../helpers/scan-qr';
|
||||
import loc from '../../loc';
|
||||
import { DetailViewStackParamList } from '../../navigation/DetailViewStackParamList';
|
||||
|
||||
const BROADCAST_RESULT = Object.freeze({
|
||||
none: 'Input transaction hex',
|
||||
@ -31,12 +32,10 @@ const BROADCAST_RESULT = Object.freeze({
|
||||
error: 'error',
|
||||
});
|
||||
|
||||
interface SuccessScreenProps {
|
||||
tx: string;
|
||||
}
|
||||
type RouteProps = RouteProp<DetailViewStackParamList, 'Broadcast'>;
|
||||
|
||||
const Broadcast: React.FC = () => {
|
||||
const { name } = useRoute();
|
||||
const { name, params } = useRoute<RouteProps>();
|
||||
const [tx, setTx] = useState<string | undefined>();
|
||||
const [txHex, setTxHex] = useState<string | undefined>();
|
||||
const { colors } = useTheme();
|
||||
@ -50,6 +49,14 @@ const Broadcast: React.FC = () => {
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const scannedData = params?.scannedData;
|
||||
if (scannedData) {
|
||||
handleScannedData(scannedData);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [params?.scannedData]);
|
||||
|
||||
const handleUpdateTxHex = (nextValue: string) => setTxHex(nextValue.trim());
|
||||
|
||||
const handleBroadcast = async () => {
|
||||
@ -81,10 +88,7 @@ const Broadcast: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleQRScan = async () => {
|
||||
const scannedData = await scanQrHelper(name);
|
||||
if (!scannedData) return;
|
||||
|
||||
const handleScannedData = (scannedData: string) => {
|
||||
if (scannedData.indexOf('+') === -1 && scannedData.indexOf('=') === -1 && scannedData.indexOf('=') === -1) {
|
||||
// this looks like NOT base64, so maybe its transaction's hex
|
||||
return handleUpdateTxHex(scannedData);
|
||||
@ -97,6 +101,10 @@ const Broadcast: React.FC = () => {
|
||||
} catch (e) {}
|
||||
};
|
||||
|
||||
const handleQRScan = () => {
|
||||
scanQrHelper(name, true, undefined, false);
|
||||
};
|
||||
|
||||
let status;
|
||||
switch (broadcastResult) {
|
||||
case BROADCAST_RESULT.none:
|
||||
@ -159,7 +167,7 @@ const Broadcast: React.FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const SuccessScreen: React.FC<SuccessScreenProps> = ({ tx }) => {
|
||||
const SuccessScreen: React.FC<{ tx: string }> = ({ tx }) => {
|
||||
if (!tx) {
|
||||
return null;
|
||||
}
|
||||
|
@ -127,9 +127,13 @@ const ScanQRCode = () => {
|
||||
const data = decoder.toString();
|
||||
decoder = false; // nullify for future use (?)
|
||||
if (launchedBy) {
|
||||
navigation.navigate({ name: launchedBy, params: {}, merge: true });
|
||||
let merge = true;
|
||||
if (typeof onBarScanned !== 'function') {
|
||||
merge = false;
|
||||
}
|
||||
navigation.navigate({ name: launchedBy, params: { scannedData: data }, merge });
|
||||
}
|
||||
onBarScanned({ data });
|
||||
onBarScanned && onBarScanned({ data });
|
||||
} else {
|
||||
setUrTotal(100);
|
||||
setUrHave(Math.floor(decoder.estimatedPercentComplete() * 100));
|
||||
@ -176,9 +180,13 @@ const ScanQRCode = () => {
|
||||
data = Buffer.from(payload, 'hex').toString();
|
||||
}
|
||||
if (launchedBy) {
|
||||
navigation.navigate({ name: launchedBy, params: {}, merge: true });
|
||||
let merge = true;
|
||||
if (typeof onBarScanned !== 'function') {
|
||||
merge = false;
|
||||
}
|
||||
navigation.navigate({ name: launchedBy, params: { scannedData: data }, merge });
|
||||
}
|
||||
onBarScanned({ data });
|
||||
onBarScanned && onBarScanned({ data });
|
||||
} else {
|
||||
setAnimatedQRCodeData(animatedQRCodeData);
|
||||
}
|
||||
@ -237,11 +245,15 @@ const ScanQRCode = () => {
|
||||
try {
|
||||
const hex = Base43.decode(ret.data);
|
||||
bitcoin.Psbt.fromHex(hex); // if it doesnt throw - all good
|
||||
|
||||
const data = Buffer.from(hex, 'hex').toString('base64');
|
||||
if (launchedBy) {
|
||||
navigation.navigate({ name: launchedBy, params: {}, merge: true });
|
||||
let merge = true;
|
||||
if (typeof onBarScanned !== 'function') {
|
||||
merge = false;
|
||||
}
|
||||
navigation.navigate({ name: launchedBy, params: { scannedData: data }, merge });
|
||||
}
|
||||
onBarScanned({ data: Buffer.from(hex, 'hex').toString('base64') });
|
||||
onBarScanned && onBarScanned({ data });
|
||||
return;
|
||||
} catch (_) {}
|
||||
|
||||
@ -249,9 +261,13 @@ const ScanQRCode = () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
if (launchedBy) {
|
||||
navigation.navigate({ name: launchedBy, params: {}, merge: true });
|
||||
let merge = true;
|
||||
if (typeof onBarScanned !== 'function') {
|
||||
merge = false;
|
||||
}
|
||||
navigation.navigate({ name: launchedBy, params: { scannedData: ret.data }, merge });
|
||||
}
|
||||
onBarScanned(ret.data);
|
||||
onBarScanned && onBarScanned(ret.data);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
@ -304,7 +320,11 @@ const ScanQRCode = () => {
|
||||
|
||||
const dismiss = () => {
|
||||
if (launchedBy) {
|
||||
navigation.navigate({ name: launchedBy, params: {}, merge: true });
|
||||
let merge = true;
|
||||
if (typeof onBarScanned !== 'function') {
|
||||
merge = false;
|
||||
}
|
||||
navigation.navigate({ name: launchedBy, params: {}, merge });
|
||||
} else {
|
||||
navigation.goBack();
|
||||
}
|
||||
|
@ -145,7 +145,6 @@ const DrawerList: React.FC<DrawerListProps> = memo(({ navigation }) => {
|
||||
<Header leftText={loc.wallets.list_title} onNewWalletPress={onNewWalletPress} isDrawerList />
|
||||
<WalletsCarousel
|
||||
data={state.wallets}
|
||||
showNewWalletPanel
|
||||
extraData={[state.wallets]}
|
||||
onPress={handleClick}
|
||||
handleLongPress={handleLongPress}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useCallback, useEffect, useReducer, useRef } from 'react';
|
||||
import { useFocusEffect, useIsFocused, useRoute } from '@react-navigation/native';
|
||||
import { useFocusEffect, useIsFocused, useRoute, RouteProp } from '@react-navigation/native';
|
||||
import { findNodeHandle, Image, InteractionManager, SectionList, StyleSheet, Text, useWindowDimensions, View } from 'react-native';
|
||||
import A from '../../blue_modules/analytics';
|
||||
import BlueClipboard from '../../blue_modules/clipboard';
|
||||
@ -88,6 +88,7 @@ function reducer(state: WalletListState, action: WalletListAction) {
|
||||
}
|
||||
|
||||
type NavigationProps = NativeStackNavigationProp<DetailViewStackParamList, 'WalletsList'>;
|
||||
type RouteProps = RouteProp<DetailViewStackParamList, 'WalletsList'>;
|
||||
|
||||
const WalletsList: React.FC = () => {
|
||||
const [state, dispatch] = useReducer<React.Reducer<WalletListState, WalletListAction>>(reducer, initialState);
|
||||
@ -108,7 +109,8 @@ const WalletsList: React.FC = () => {
|
||||
const { colors, scanImage } = useTheme();
|
||||
const { navigate } = useExtendedNavigation<NavigationProps>();
|
||||
const isFocused = useIsFocused();
|
||||
const routeName = useRoute().name;
|
||||
const route = useRoute<RouteProps>();
|
||||
const routeName = route.name;
|
||||
const dataSource = getTransactions(undefined, 10);
|
||||
const walletsCount = useRef<number>(wallets.length);
|
||||
const walletActionButtonsRef = useRef<any>();
|
||||
@ -149,6 +151,14 @@ const WalletsList: React.FC = () => {
|
||||
walletsCount.current = wallets.length;
|
||||
}, [wallets]);
|
||||
|
||||
useEffect(() => {
|
||||
const scannedData = route.params?.scannedData;
|
||||
if (scannedData) {
|
||||
onBarScanned(scannedData);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [route.params?.scannedData]);
|
||||
|
||||
const verifyBalance = useCallback(() => {
|
||||
if (getBalance() !== 0) {
|
||||
A(A.ENUM.GOT_NONZERO_BALANCE);
|
||||
@ -253,7 +263,6 @@ const WalletsList: React.FC = () => {
|
||||
handleLongPress={handleLongPress}
|
||||
onMomentumScrollEnd={onSnapToItem}
|
||||
ref={walletsCarousel}
|
||||
showNewWalletPanel
|
||||
onNewWalletPress={handleClick}
|
||||
testID="WalletsList"
|
||||
horizontal
|
||||
@ -332,9 +341,8 @@ const WalletsList: React.FC = () => {
|
||||
};
|
||||
|
||||
const onScanButtonPressed = useCallback(() => {
|
||||
scanQrHelper(routeName).then(onBarScanned);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
scanQrHelper(routeName, true, undefined, false);
|
||||
}, [routeName]);
|
||||
|
||||
const onBarScanned = useCallback(
|
||||
(value: any) => {
|
||||
@ -381,7 +389,7 @@ const WalletsList: React.FC = () => {
|
||||
});
|
||||
break;
|
||||
case 2:
|
||||
scanQrHelper(routeName, true).then(data => onBarScanned(data));
|
||||
scanQrHelper(routeName, true, undefined, false);
|
||||
break;
|
||||
case 3:
|
||||
if (!isClipboardEmpty) {
|
||||
|
@ -24,6 +24,7 @@ const WalletsImport = () => {
|
||||
const route = useRoute();
|
||||
const label = route?.params?.label ?? '';
|
||||
const triggerImport = route?.params?.triggerImport ?? false;
|
||||
const scannedData = route?.params?.scannedData ?? '';
|
||||
const { isAdvancedModeEnabled } = useSettings();
|
||||
const [importText, setImportText] = useState(label);
|
||||
const [isToolbarVisibleForAndroid, setIsToolbarVisibleForAndroid] = useState(false);
|
||||
@ -76,7 +77,14 @@ const WalletsImport = () => {
|
||||
useEffect(() => {
|
||||
if (triggerImport) importButtonPressed();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
}, [triggerImport]);
|
||||
|
||||
useEffect(() => {
|
||||
if (scannedData) {
|
||||
onBarScanned(scannedData);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [scannedData]);
|
||||
|
||||
const importButtonPressed = () => {
|
||||
const textToImport = onBlur();
|
||||
@ -102,7 +110,6 @@ const WalletsImport = () => {
|
||||
screen: 'ScanQRCode',
|
||||
params: {
|
||||
launchedBy: route.name,
|
||||
onBarScanned,
|
||||
showFileImportButton: true,
|
||||
},
|
||||
}),
|
||||
|
Loading…
Reference in New Issue
Block a user