Merge branch 'master' into tooltipfix

This commit is contained in:
Marcos Rodriguez Velez 2024-05-26 18:18:17 -04:00
commit d605f75745
No known key found for this signature in database
GPG key ID: 6030B2F48CCE86D7
15 changed files with 205 additions and 102 deletions

View file

@ -1,7 +1,13 @@
// https://levelup.gitconnected.com/debounce-in-javascript-improve-your-applications-performance-5b01855e086 // https://levelup.gitconnected.com/debounce-in-javascript-improve-your-applications-performance-5b01855e086
const debounce = <T extends (...args: any[]) => void>(func: T, wait: number) => { // blue_modules/debounce.ts
type DebouncedFunction<T extends (...args: any[]) => void> = {
(this: ThisParameterType<T>, ...args: Parameters<T>): void;
cancel(): void;
};
const debounce = <T extends (...args: any[]) => void>(func: T, wait: number): DebouncedFunction<T> => {
let timeout: NodeJS.Timeout | null; let timeout: NodeJS.Timeout | null;
return function executedFunction(this: ThisParameterType<T>, ...args: Parameters<T>) { const debouncedFunction = function (this: ThisParameterType<T>, ...args: Parameters<T>) {
const later = () => { const later = () => {
timeout = null; timeout = null;
func.apply(this, args); func.apply(this, args);
@ -11,6 +17,15 @@ const debounce = <T extends (...args: any[]) => void>(func: T, wait: number) =>
} }
timeout = setTimeout(later, wait); timeout = setTimeout(later, wait);
}; };
debouncedFunction.cancel = () => {
if (timeout) {
clearTimeout(timeout);
}
timeout = null;
};
return debouncedFunction as DebouncedFunction<T>;
}; };
export default debounce; export default debounce;

View file

@ -1,4 +1,3 @@
import { useNavigation } from '@react-navigation/native';
import React from 'react'; import React from 'react';
import { Image, Keyboard, StyleSheet, Text, TextInput, View } from 'react-native'; import { Image, Keyboard, StyleSheet, Text, TextInput, View } from 'react-native';
@ -51,7 +50,6 @@ const AddressInput = ({
keyboardType = 'default', keyboardType = 'default',
}: AddressInputProps) => { }: AddressInputProps) => {
const { colors } = useTheme(); const { colors } = useTheme();
const { navigate } = useNavigation();
const stylesHook = StyleSheet.create({ const stylesHook = StyleSheet.create({
root: { root: {
borderColor: colors.formBorder, borderColor: colors.formBorder,
@ -77,7 +75,7 @@ const AddressInput = ({
case actionKeys.ScanQR: case actionKeys.ScanQR:
scanButtonTapped(); scanButtonTapped();
if (launchedBy) { if (launchedBy) {
scanQrHelper(navigate, launchedBy) scanQrHelper(launchedBy)
.then(value => onBarScanned({ data: value })) .then(value => onBarScanned({ data: value }))
.catch(error => { .catch(error => {
presentAlert({ message: error.message }); presentAlert({ message: error.message });

View file

@ -1,23 +1,17 @@
import { Platform } from 'react-native'; import { Platform } from 'react-native';
import { check, request, PERMISSIONS, RESULTS } from 'react-native-permissions'; import { check, request, PERMISSIONS, RESULTS } from 'react-native-permissions';
import { navigationRef } from '../NavigationService';
/** /**
* Helper function that navigates to ScanQR screen, and returns promise that will resolve with the result of a scan, * Helper function that navigates to ScanQR screen, and returns promise that will resolve with the result of a scan,
* and then navigates back. If QRCode scan was closed, promise resolves to null. * and then navigates back. If QRCode scan was closed, promise resolves to null.
* *
* @param navigateFunc {function}
* @param currentScreenName {string} * @param currentScreenName {string}
* @param showFileImportButton {boolean} * @param showFileImportButton {boolean}
* *
* @param onDismiss {function} - if camera is closed via X button it gets triggered * @param onDismiss {function} - if camera is closed via X button it gets triggered
* @return {Promise<string>} * @return {Promise<string>}
*/ */
function scanQrHelper( function scanQrHelper(currentScreenName: string, showFileImportButton = true, onDismiss?: () => void): Promise<string | null> {
navigateFunc: (scr: string | any, params?: any) => void,
currentScreenName: string,
showFileImportButton = true,
onDismiss?: () => void,
): Promise<string | null> {
return requestCameraAuthorization().then(() => { return requestCameraAuthorization().then(() => {
return new Promise(resolve => { return new Promise(resolve => {
const params = { const params = {
@ -28,10 +22,10 @@ function scanQrHelper(
params.onBarScanned = function (data: any) { params.onBarScanned = function (data: any) {
setTimeout(() => resolve(data.data || data), 1); setTimeout(() => resolve(data.data || data), 1);
navigateFunc({ name: currentScreenName, params: {}, merge: true }); navigationRef.navigate({ name: currentScreenName, params: {}, merge: true });
}; };
navigateFunc('ScanQRCodeRoot', { navigationRef.navigate('ScanQRCodeRoot', {
screen: 'ScanQRCode', screen: 'ScanQRCode',
params, params,
}); });

23
hooks/useDebounce.ts Normal file
View file

@ -0,0 +1,23 @@
import { useState, useEffect } from 'react';
import debounce from '../blue_modules/debounce';
const useDebounce = <T>(value: T, delay: number): T => {
const [debouncedValue, setDebouncedValue] = useState<T>(value);
useEffect(() => {
const handler = debounce((val: T) => {
setDebouncedValue(val);
}, delay);
handler(value);
return () => {
handler.cancel();
};
}, [value, delay]);
return debouncedValue;
};
export default useDebounce;

View file

@ -186,6 +186,7 @@ export type TFiatUnit = {
endPointKey: string; endPointKey: string;
symbol: string; symbol: string;
locale: string; locale: string;
country: string;
source: 'CoinDesk' | 'Yadio' | 'Exir' | 'wazirx' | 'Bitstamp' | 'Kraken'; source: 'CoinDesk' | 'Yadio' | 'Exir' | 'wazirx' | 'Bitstamp' | 'Kraken';
}; };
@ -199,6 +200,7 @@ export type FiatUnitType = {
endPointKey: string; endPointKey: string;
symbol: string; symbol: string;
locale: string; locale: string;
country: string;
source: keyof typeof FiatUnitSource; source: keyof typeof FiatUnitSource;
}; };

View file

@ -3,336 +3,392 @@
"endPointKey": "USD", "endPointKey": "USD",
"locale": "en-US", "locale": "en-US",
"source": "Kraken", "source": "Kraken",
"symbol": "$" "symbol": "$",
"country": "United States (US Dollar)"
}, },
"AED": { "AED": {
"endPointKey": "AED", "endPointKey": "AED",
"locale": "ar-AE", "locale": "ar-AE",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "د.إ." "symbol": "د.إ.",
"country": "United Arab Emirates (UAE Dirham)"
}, },
"ANG": { "ANG": {
"endPointKey": "ANG", "endPointKey": "ANG",
"locale": "en-SX", "locale": "en-SX",
"source": "CoinDesk", "source": "CoinDesk",
"symbol": "ƒ" "symbol": "ƒ",
"country": "Sint Maarten (Netherlands Antillean Guilder)"
}, },
"ARS": { "ARS": {
"endPointKey": "ARS", "endPointKey": "ARS",
"locale": "es-AR", "locale": "es-AR",
"source": "Yadio", "source": "Yadio",
"symbol": "$" "symbol": "$",
"country": "Argentina (Argentine Peso)"
}, },
"AUD": { "AUD": {
"endPointKey": "AUD", "endPointKey": "AUD",
"locale": "en-AU", "locale": "en-AU",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "$" "symbol": "$",
"country": "Australia (Australian Dollar)"
}, },
"AWG": { "AWG": {
"endPointKey": "AWG", "endPointKey": "AWG",
"locale": "nl-AW", "locale": "nl-AW",
"source": "CoinDesk", "source": "CoinDesk",
"symbol": "ƒ" "symbol": "ƒ",
"country": "Aruba (Aruban Florin)"
}, },
"BHD": { "BHD": {
"endPointKey": "BHD", "endPointKey": "BHD",
"locale": "ar-BH", "locale": "ar-BH",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "د.ب." "symbol": "د.ب.",
"country": "Bahrain (Bahraini Dinar)"
}, },
"BRL": { "BRL": {
"endPointKey": "BRL", "endPointKey": "BRL",
"locale": "pt-BR", "locale": "pt-BR",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "R$" "symbol": "R$",
"country": "Brazil (Brazilian Real)"
}, },
"CAD": { "CAD": {
"endPointKey": "CAD", "endPointKey": "CAD",
"locale": "en-CA", "locale": "en-CA",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "$" "symbol": "$",
"country": "Canada (Canadian Dollar)"
}, },
"CHF": { "CHF": {
"endPointKey": "CHF", "endPointKey": "CHF",
"locale": "de-CH", "locale": "de-CH",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "CHF" "symbol": "CHF",
"country": "Switzerland (Swiss Franc)"
}, },
"CLP": { "CLP": {
"endPointKey": "CLP", "endPointKey": "CLP",
"locale": "es-CL", "locale": "es-CL",
"source": "Yadio", "source": "Yadio",
"symbol": "$" "symbol": "$",
"country": "Chile (Chilean Peso)"
}, },
"CNY": { "CNY": {
"endPointKey": "CNY", "endPointKey": "CNY",
"locale": "zh-CN", "locale": "zh-CN",
"source": "Coinbase", "source": "Coinbase",
"symbol": "¥" "symbol": "¥",
"country": "China (Chinese Yuan)"
}, },
"COP": { "COP": {
"endPointKey": "COP", "endPointKey": "COP",
"locale": "es-CO", "locale": "es-CO",
"source": "CoinDesk", "source": "CoinDesk",
"symbol": "$" "symbol": "$",
"country": "Colombia (Colombian Peso)"
}, },
"CZK": { "CZK": {
"endPointKey": "CZK", "endPointKey": "CZK",
"locale": "cs-CZ", "locale": "cs-CZ",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "Kč" "symbol": "Kč",
"country": "Czech Republic (Czech Koruna)"
}, },
"DKK": { "DKK": {
"endPointKey": "DKK", "endPointKey": "DKK",
"locale": "da-DK", "locale": "da-DK",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "kr" "symbol": "kr",
"country": "Denmark (Danish Krone)"
}, },
"EUR": { "EUR": {
"endPointKey": "EUR", "endPointKey": "EUR",
"locale": "en-IE", "locale": "en-IE",
"source": "Kraken", "source": "Kraken",
"symbol": "€" "symbol": "€",
"country": "European Union (Euro)"
}, },
"GBP": { "GBP": {
"endPointKey": "GBP", "endPointKey": "GBP",
"locale": "en-GB", "locale": "en-GB",
"source": "Kraken", "source": "Kraken",
"symbol": "£" "symbol": "£",
"country": "United Kingdom (British Pound)"
}, },
"HRK": { "HRK": {
"endPointKey": "HRK", "endPointKey": "HRK",
"locale": "hr-HR", "locale": "hr-HR",
"source": "CoinDesk", "source": "CoinDesk",
"symbol": "HRK" "symbol": "HRK",
"country": "Croatia (Croatian Kuna)"
}, },
"HUF": { "HUF": {
"endPointKey": "HUF", "endPointKey": "HUF",
"locale": "hu-HU", "locale": "hu-HU",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "Ft" "symbol": "Ft",
"country": "Hungary (Hungarian Forint)"
}, },
"IDR": { "IDR": {
"endPointKey": "IDR", "endPointKey": "IDR",
"locale": "id-ID", "locale": "id-ID",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "Rp" "symbol": "Rp",
"country": "Indonesia (Indonesian Rupiah)"
}, },
"ILS": { "ILS": {
"endPointKey": "ILS", "endPointKey": "ILS",
"locale": "he-IL", "locale": "he-IL",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "₪" "symbol": "₪",
"country": "Israel (Israeli New Shekel)"
}, },
"INR": { "INR": {
"endPointKey": "INR", "endPointKey": "INR",
"locale": "hi-HN", "locale": "hi-IN",
"source": "wazirx", "source": "wazirx",
"symbol": "₹" "symbol": "₹",
"country": "India (Indian Rupee)"
}, },
"IRR": { "IRR": {
"endPointKey": "IRR", "endPointKey": "IRR",
"locale": "fa-IR", "locale": "fa-IR",
"source": "Exir", "source": "Exir",
"symbol": "﷼" "symbol": "﷼",
"country": "Iran (Iranian Rial)"
}, },
"IRT": { "IRT": {
"endPointKey": "IRT", "endPointKey": "IRT",
"locale": "fa-IR", "locale": "fa-IR",
"source": "Exir", "source": "Exir",
"symbol": "تومان" "symbol": "تومان",
"country": "Iran (Iranian Toman)"
}, },
"ISK": { "ISK": {
"endPointKey": "ISK", "endPointKey": "ISK",
"locale": "is-IS", "locale": "is-IS",
"source": "CoinDesk", "source": "CoinDesk",
"symbol": "kr" "symbol": "kr",
"country": "Iceland (Icelandic Króna)"
}, },
"JPY": { "JPY": {
"endPointKey": "JPY", "endPointKey": "JPY",
"locale": "ja-JP", "locale": "ja-JP",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "¥" "symbol": "¥",
"country": "Japan (Japanese Yen)"
}, },
"KES": { "KES": {
"endPointKey": "KES", "endPointKey": "KES",
"locale": "en-KE", "locale": "en-KE",
"source": "CoinDesk", "source": "CoinDesk",
"symbol": "Ksh" "symbol": "Ksh",
"country": "Kenya (Kenyan Shilling)"
}, },
"KRW": { "KRW": {
"endPointKey": "KRW", "endPointKey": "KRW",
"locale": "ko-KR", "locale": "ko-KR",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "₩" "symbol": "₩",
"country": "South Korea (South Korean Won)"
}, },
"KWD": { "KWD": {
"endPointKey": "KWD", "endPointKey": "KWD",
"locale": "ar-KW", "locale": "ar-KW",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "د.ك." "symbol": "د.ك.",
"country": "Kuwait (Kuwaiti Dinar)"
}, },
"LBP": { "LBP": {
"endPointKey": "LBP", "endPointKey": "LBP",
"locale": "ar-LB", "locale": "ar-LB",
"source": "YadioConvert", "source": "YadioConvert",
"symbol": "ل.ل." "symbol": "ل.ل.",
"country": "Lebanon (Lebanese Pound)"
}, },
"LKR": { "LKR": {
"endPointKey": "LKR", "endPointKey": "LKR",
"locale": "si-LK", "locale": "si-LK",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "රු." "symbol": "රු.",
"country": "Sri Lanka (Sri Lankan Rupee)"
}, },
"MXN": { "MXN": {
"endPointKey": "MXN", "endPointKey": "MXN",
"locale": "es-MX", "locale": "es-MX",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "$" "symbol": "$",
"country": "Mexico (Mexican Peso)"
}, },
"MYR": { "MYR": {
"endPointKey": "MYR", "endPointKey": "MYR",
"locale": "ms-MY", "locale": "ms-MY",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "RM" "symbol": "RM",
"country": "Malaysia (Malaysian Ringgit)"
}, },
"MZN": { "MZN": {
"endPointKey": "MZN", "endPointKey": "MZN",
"locale": "seh-MZ", "locale": "seh-MZ",
"source": "CoinDesk", "source": "CoinDesk",
"symbol": "MTn" "symbol": "MTn",
"country": "Mozambique (Mozambican Metical)"
}, },
"NGN": { "NGN": {
"endPointKey": "NGN", "endPointKey": "NGN",
"locale": "en-NG", "locale": "en-NG",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "₦" "symbol": "₦",
"country": "Nigeria (Nigerian Naira)"
}, },
"NOK": { "NOK": {
"endPointKey": "NOK", "endPointKey": "NOK",
"locale": "nb-NO", "locale": "nb-NO",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "kr" "symbol": "kr",
"country": "Norway (Norwegian Krone)"
}, },
"NZD": { "NZD": {
"endPointKey": "NZD", "endPointKey": "NZD",
"locale": "en-NZ", "locale": "en-NZ",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "$" "symbol": "$",
"country": "New Zealand (New Zealand Dollar)"
}, },
"OMR": { "OMR": {
"endPointKey": "OMR", "endPointKey": "OMR",
"locale": "ar-OM", "locale": "ar-OM",
"source": "CoinDesk", "source": "CoinDesk",
"symbol": "ر.ع." "symbol": "ر.ع.",
"country": "Oman (Omani Rial)"
}, },
"PHP": { "PHP": {
"endPointKey": "PHP", "endPointKey": "PHP",
"locale": "en-PH", "locale": "en-PH",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "₱" "symbol": "₱",
"country": "Philippines (Philippine Peso)"
}, },
"PLN": { "PLN": {
"endPointKey": "PLN", "endPointKey": "PLN",
"locale": "pl-PL", "locale": "pl-PL",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "zł" "symbol": "zł",
"country": "Poland (Polish Zloty)"
}, },
"QAR": { "QAR": {
"endPointKey": "QAR", "endPointKey": "QAR",
"locale": "ar-QA", "locale": "ar-QA",
"source": "CoinDesk", "source": "CoinDesk",
"symbol": "ر.ق." "symbol": "ر.ق.",
"country": "Qatar (Qatari Riyal)"
}, },
"RON": { "RON": {
"endPointKey": "RON", "endPointKey": "RON",
"locale": "ro-RO", "locale": "ro-RO",
"source": "BNR", "source": "BNR",
"symbol": "lei" "symbol": "lei",
"country": "Romania (Romanian Leu)"
}, },
"RUB": { "RUB": {
"endPointKey": "RUB", "endPointKey": "RUB",
"locale": "ru-RU", "locale": "ru-RU",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "₽" "symbol": "₽",
"country": "Russia (Russian Ruble)"
}, },
"SAR": { "SAR": {
"endPointKey": "SAR", "endPointKey": "SAR",
"locale": "ar-SA", "locale": "ar-SA",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "ر.س." "symbol": "ر.س.",
"country": "Saudi Arabia (Saudi Riyal)"
}, },
"SEK": { "SEK": {
"endPointKey": "SEK", "endPointKey": "SEK",
"locale": "sv-SE", "locale": "sv-SE",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "kr" "symbol": "kr",
"country": "Sweden (Swedish Krona)"
}, },
"SGD": { "SGD": {
"endPointKey": "SGD", "endPointKey": "SGD",
"locale": "zh-SG", "locale": "zh-SG",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "S$" "symbol": "S$",
"country": "Singapore (Singapore Dollar)"
}, },
"THB": { "THB": {
"endPointKey": "THB", "endPointKey": "THB",
"locale": "th-TH", "locale": "th-TH",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "฿" "symbol": "฿",
"country": "Thailand (Thai Baht)"
}, },
"TRY": { "TRY": {
"endPointKey": "TRY", "endPointKey": "TRY",
"locale": "tr-TR", "locale": "tr-TR",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "₺" "symbol": "₺",
"country": "Turkey (Turkish Lira)"
}, },
"TWD": { "TWD": {
"endPointKey": "TWD", "endPointKey": "TWD",
"locale": "zh-Hant-TW", "locale": "zh-Hant-TW",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "NT$" "symbol": "NT$",
"country": "Taiwan (New Taiwan Dollar)"
}, },
"TZS": { "TZS": {
"endPointKey": "TZS", "endPointKey": "TZS",
"locale": "en-TZ", "locale": "en-TZ",
"source": "CoinDesk", "source": "CoinDesk",
"symbol": "TSh" "symbol": "TSh",
"country": "Tanzania (Tanzanian Shilling)"
}, },
"UAH": { "UAH": {
"endPointKey": "UAH", "endPointKey": "UAH",
"locale": "uk-UA", "locale": "uk-UA",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "₴" "symbol": "₴",
"country": "Ukraine (Ukrainian Hryvnia)"
}, },
"UGX": { "UGX": {
"endPointKey": "UGX", "endPointKey": "UGX",
"locale": "en-UG", "locale": "en-UG",
"source": "CoinDesk", "source": "CoinDesk",
"symbol": "USh" "symbol": "USh",
"country": "Uganda (Ugandan Shilling)"
}, },
"UYU": { "UYU": {
"endPointKey": "UYU", "endPointKey": "UYU",
"locale": "es-UY", "locale": "es-UY",
"source": "CoinDesk", "source": "CoinDesk",
"symbol": "$" "symbol": "$",
"country": "Uruguay (Uruguayan Peso)"
}, },
"VEF": { "VEF": {
"endPointKey": "VEF", "endPointKey": "VEF",
"locale": "es-VE", "locale": "es-VE",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "Bs." "symbol": "Bs.",
"country": "Venezuela (Venezuelan Bolívar Fuerte)"
}, },
"VES": { "VES": {
"endPointKey": "VES", "endPointKey": "VES",
"locale": "es-VE", "locale": "es-VE",
"source": "Yadio", "source": "Yadio",
"symbol": "Bs." "symbol": "Bs.",
"country": "Venezuela (Venezuelan Bolívar Soberano)"
}, },
"ZAR": { "ZAR": {
"endPointKey": "ZAR", "endPointKey": "ZAR",
"locale": "en-ZA", "locale": "en-ZA",
"source": "CoinGecko", "source": "CoinGecko",
"symbol": "R" "symbol": "R",
"country": "South Africa (South African Rand)"
} }
} }

View file

@ -1,6 +1,6 @@
import { useNavigation, useRoute } from '@react-navigation/native';
import * as bitcoin from 'bitcoinjs-lib';
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useRoute } from '@react-navigation/native';
import * as bitcoin from 'bitcoinjs-lib';
import { ActivityIndicator, Keyboard, KeyboardAvoidingView, Linking, Platform, StyleSheet, TextInput, View } from 'react-native'; import { ActivityIndicator, Keyboard, KeyboardAvoidingView, Linking, Platform, StyleSheet, TextInput, View } from 'react-native';
import * as BlueElectrum from '../../blue_modules/BlueElectrum'; import * as BlueElectrum from '../../blue_modules/BlueElectrum';
@ -37,7 +37,6 @@ interface SuccessScreenProps {
const Broadcast: React.FC = () => { const Broadcast: React.FC = () => {
const { name } = useRoute(); const { name } = useRoute();
const { navigate } = useNavigation();
const [tx, setTx] = useState<string | undefined>(); const [tx, setTx] = useState<string | undefined>();
const [txHex, setTxHex] = useState<string | undefined>(); const [txHex, setTxHex] = useState<string | undefined>();
const { colors } = useTheme(); const { colors } = useTheme();
@ -83,7 +82,7 @@ const Broadcast: React.FC = () => {
}; };
const handleQRScan = async () => { const handleQRScan = async () => {
const scannedData = await scanQrHelper(navigate, name); const scannedData = await scanQrHelper(name);
if (!scannedData) return; if (!scannedData) return;
if (scannedData.indexOf('+') === -1 && scannedData.indexOf('=') === -1 && scannedData.indexOf('=') === -1) { if (scannedData.indexOf('+') === -1 && scannedData.indexOf('=') === -1 && scannedData.indexOf('=') === -1) {

View file

@ -857,7 +857,7 @@ const SendDetails = () => {
setIsLoading(true); setIsLoading(true);
setOptionsVisible(false); setOptionsVisible(false);
await new Promise(resolve => setTimeout(resolve, 100)); // sleep for animations await new Promise(resolve => setTimeout(resolve, 100)); // sleep for animations
const scannedData = await scanQrHelper(navigation.navigate, name); const scannedData = await scanQrHelper(name);
if (!scannedData) return setIsLoading(false); if (!scannedData) return setIsLoading(false);
let tx; let tx;

View file

@ -60,7 +60,7 @@ const PsbtMultisigQRCode = () => {
}; };
const openScanner = async () => { const openScanner = async () => {
const scanned = await scanQrHelper(navigate, name, true); const scanned = await scanQrHelper(name, true);
onBarScanned({ data: scanned }); onBarScanned({ data: scanned });
}; };

View file

@ -18,6 +18,7 @@ import { useTheme } from '../../components/themes';
import { useExtendedNavigation } from '../../hooks/useExtendedNavigation'; import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
import loc from '../../loc'; import loc from '../../loc';
import { FiatUnit, FiatUnitSource, FiatUnitType, getFiatRate } from '../../models/fiatUnit'; import { FiatUnit, FiatUnitSource, FiatUnitType, getFiatRate } from '../../models/fiatUnit';
import useDebounce from '../../hooks/useDebounce';
dayjs.extend(calendar); dayjs.extend(calendar);
@ -26,13 +27,20 @@ const Currency: React.FC = () => {
const [isSavingNewPreferredCurrency, setIsSavingNewPreferredCurrency] = useState(false); const [isSavingNewPreferredCurrency, setIsSavingNewPreferredCurrency] = useState(false);
const [selectedCurrency, setSelectedCurrency] = useState<FiatUnitType>(FiatUnit.USD); const [selectedCurrency, setSelectedCurrency] = useState<FiatUnitType>(FiatUnit.USD);
const [currencyRate, setCurrencyRate] = useState<CurrencyRate>({ LastUpdated: null, Rate: null }); const [currencyRate, setCurrencyRate] = useState<CurrencyRate>({ LastUpdated: null, Rate: null });
const [isSearchFocused, setIsSearchFocused] = useState(false);
const { colors } = useTheme(); const { colors } = useTheme();
const { setOptions } = useExtendedNavigation(); const { setOptions } = useExtendedNavigation();
const [search, setSearch] = useState(''); const [search, setSearch] = useState('');
const debouncedSearch = useDebounce(search, 300);
const data = useMemo( const data = useMemo(
() => Object.values(FiatUnit).filter(item => item.endPointKey.toLowerCase().includes(search.toLowerCase())), () =>
[search], Object.values(FiatUnit).filter(
item =>
item.endPointKey.toLowerCase().includes(debouncedSearch.toLowerCase()) ||
item.country.toLowerCase().includes(debouncedSearch.toLowerCase()),
),
[debouncedSearch],
); );
const stylesHook = StyleSheet.create({ const stylesHook = StyleSheet.create({
@ -64,6 +72,8 @@ const Currency: React.FC = () => {
setOptions({ setOptions({
headerSearchBarOptions: { headerSearchBarOptions: {
onChangeText: (event: NativeSyntheticEvent<{ text: string }>) => setSearch(event.nativeEvent.text), onChangeText: (event: NativeSyntheticEvent<{ text: string }>) => setSearch(event.nativeEvent.text),
onFocus: () => setIsSearchFocused(true),
onBlur: () => setIsSearchFocused(false),
}, },
}); });
}, [setOptions]); }, [setOptions]);
@ -74,6 +84,7 @@ const Currency: React.FC = () => {
title={`${item.endPointKey} (${item.symbol})`} title={`${item.endPointKey} (${item.symbol})`}
containerStyle={StyleSheet.flatten([styles.flex, stylesHook.flex, { minHeight: 60 }])} containerStyle={StyleSheet.flatten([styles.flex, stylesHook.flex, { minHeight: 60 }])}
checkmark={selectedCurrency.endPointKey === item.endPointKey} checkmark={selectedCurrency.endPointKey === item.endPointKey}
subtitle={item.country}
onPress={async () => { onPress={async () => {
setIsSavingNewPreferredCurrency(true); setIsSavingNewPreferredCurrency(true);
try { try {
@ -86,7 +97,7 @@ const Currency: React.FC = () => {
} catch (error: any) { } catch (error: any) {
console.log(error); console.log(error);
presentAlert({ presentAlert({
message: error.message ? `${loc.settings.currency_fetch_error}: ${error.message}}` : loc.settings.currency_fetch_error, message: error.message ? `${loc.settings.currency_fetch_error}: ${error.message}` : loc.settings.currency_fetch_error,
}); });
} finally { } finally {
setIsSavingNewPreferredCurrency(false); setIsSavingNewPreferredCurrency(false);
@ -95,6 +106,11 @@ const Currency: React.FC = () => {
/> />
); );
const selectedCurrencyVisible = useMemo(
() => data.some(item => item.endPointKey === selectedCurrency.endPointKey),
[data, selectedCurrency],
);
return ( return (
<View style={[styles.flex, stylesHook.flex]}> <View style={[styles.flex, stylesHook.flex]}>
<FlatList <FlatList
@ -105,19 +121,21 @@ const Currency: React.FC = () => {
initialNumToRender={30} initialNumToRender={30}
renderItem={renderItem} renderItem={renderItem}
/> />
<BlueCard> {!isSearchFocused || selectedCurrencyVisible ? (
<BlueText> <BlueCard>
{loc.settings.currency_source} {selectedCurrency?.source ?? FiatUnitSource.CoinDesk} <BlueText>
</BlueText> {loc.settings.currency_source} {selectedCurrency?.source ?? FiatUnitSource.CoinDesk}
<BlueSpacing10 /> </BlueText>
<BlueText> <BlueSpacing10 />
{loc.settings.rate}: {currencyRate.Rate ?? loc._.never} <BlueText>
</BlueText> {loc.settings.rate}: {currencyRate.Rate ?? loc._.never}
<BlueSpacing10 /> </BlueText>
<BlueText> <BlueSpacing10 />
{loc.settings.last_updated}: {dayjs(currencyRate.LastUpdated).calendar() ?? loc._.never} <BlueText>
</BlueText> {loc.settings.last_updated}: {dayjs(currencyRate.LastUpdated).calendar() ?? loc._.never}
</BlueCard> </BlueText>
</BlueCard>
) : null}
</View> </View>
); );
}; };

View file

@ -36,7 +36,6 @@ import ListItem from '../../components/ListItem';
import { BlueCurrentTheme } from '../../components/themes'; import { BlueCurrentTheme } from '../../components/themes';
import { scanQrHelper } from '../../helpers/scan-qr'; import { scanQrHelper } from '../../helpers/scan-qr';
import loc from '../../loc'; import loc from '../../loc';
import { navigationRef } from '../../NavigationService';
export default class ElectrumSettings extends Component { export default class ElectrumSettings extends Component {
static contextType = BlueStorageContext; static contextType = BlueStorageContext;
@ -225,7 +224,7 @@ export default class ElectrumSettings extends Component {
}; };
importScan = async () => { importScan = async () => {
const scanned = await scanQrHelper(navigationRef.navigate, 'ElectrumSettings', true); const scanned = await scanQrHelper('ElectrumSettings', true);
this.onBarScanned(scanned); this.onBarScanned(scanned);
}; };

View file

@ -51,7 +51,6 @@ import { useBiometrics } from '../../hooks/useBiometrics';
import { useExtendedNavigation } from '../../hooks/useExtendedNavigation'; import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
import usePrivacy from '../../hooks/usePrivacy'; import usePrivacy from '../../hooks/usePrivacy';
import loc from '../../loc'; import loc from '../../loc';
import * as NavigationService from '../../NavigationService';
import ActionSheet from '../ActionSheet'; import ActionSheet from '../ActionSheet';
const ViewEditMultisigCosigners: React.FC = () => { const ViewEditMultisigCosigners: React.FC = () => {
@ -513,7 +512,7 @@ const ViewEditMultisigCosigners: React.FC = () => {
const scanOrOpenFile = async () => { const scanOrOpenFile = async () => {
setIsProvideMnemonicsModalVisible(false); setIsProvideMnemonicsModalVisible(false);
const scanned = await scanQrHelper(NavigationService.navigate, route.name, true); const scanned = await scanQrHelper(route.name, true);
setImportText(String(scanned)); setImportText(String(scanned));
setIsProvideMnemonicsModalVisible(true); setIsProvideMnemonicsModalVisible(true);
}; };

View file

@ -318,7 +318,7 @@ const WalletsList: React.FC = () => {
}; };
const onScanButtonPressed = () => { const onScanButtonPressed = () => {
scanQrHelper(navigate, routeName).then(onBarScanned); scanQrHelper(routeName).then(onBarScanned);
}; };
const onBarScanned = (value: any) => { const onBarScanned = (value: any) => {
@ -364,7 +364,7 @@ const WalletsList: React.FC = () => {
}); });
break; break;
case 2: case 2:
scanQrHelper(navigate, routeName, true).then(data => onBarScanned(data)); scanQrHelper(routeName, true).then(data => onBarScanned(data));
break; break;
case 3: case 3:
if (!isClipboardEmpty) { if (!isClipboardEmpty) {

View file

@ -461,7 +461,7 @@ const WalletsAddMultisigStep2 = () => {
const scanOrOpenFile = () => { const scanOrOpenFile = () => {
setIsProvideMnemonicsModalVisible(false); setIsProvideMnemonicsModalVisible(false);
InteractionManager.runAfterInteractions(async () => { InteractionManager.runAfterInteractions(async () => {
const scanned = await scanQrHelper(navigation.navigate, name, true); const scanned = await scanQrHelper(name, true);
onBarScanned({ data: scanned }); onBarScanned({ data: scanned });
}); });
}; };

View file

@ -409,7 +409,7 @@ const WalletTransactions = ({ navigation }) => {
choosePhoto(); choosePhoto();
break; break;
case 2: case 2:
scanQrHelper(navigate, name, true).then(data => onBarCodeRead(data)); scanQrHelper(name, true).then(data => onBarCodeRead(data));
break; break;
case 3: case 3:
if (!isClipboardEmpty) { if (!isClipboardEmpty) {