From 5850ec3faadd7824339112c20c828a556c0daf37 Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Sat, 25 May 2024 17:50:46 -0400 Subject: [PATCH 01/18] FIX: Tooltip was in ocassions missing styles --- components/AddressInput.tsx | 42 +++++++++++++++++----------------- components/QRCodeComponent.tsx | 9 +++++++- components/TooltipMenu.ios.tsx | 11 ++++++--- components/types.ts | 7 +++++- 4 files changed, 43 insertions(+), 26 deletions(-) diff --git a/components/AddressInput.tsx b/components/AddressInput.tsx index 846e4fa71..8136d57af 100644 --- a/components/AddressInput.tsx +++ b/components/AddressInput.tsx @@ -1,6 +1,6 @@ import { useNavigation } from '@react-navigation/native'; import React from 'react'; -import { Image, Keyboard, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native'; +import { Image, Keyboard, StyleSheet, Text, TextInput, View } from 'react-native'; import { scanQrHelper } from '../helpers/scan-qr'; import loc from '../loc'; @@ -137,26 +137,26 @@ const AddressInput = ({ keyboardType={keyboardType} /> {editable ? ( - - { - await scanButtonTapped(); - Keyboard.dismiss(); - // @ts-ignore: Fix later - scanQrHelper(navigate, launchedBy).then(onBarScanned); - }} - accessibilityRole="button" - style={[styles.scan, stylesHook.scan]} - accessibilityLabel={loc.send.details_scan} - accessibilityHint={loc.send.details_scan_hint} - > - - - {loc.send.details_scan} - - + { + await scanButtonTapped(); + Keyboard.dismiss(); + // @ts-ignore: Fix later + scanQrHelper(navigate, launchedBy).then(onBarScanned); + }} + style={[styles.scan, stylesHook.scan]} + accessibilityLabel={loc.send.details_scan} + accessibilityHint={loc.send.details_scan_hint} + > + + + {loc.send.details_scan} + ) : null} diff --git a/components/QRCodeComponent.tsx b/components/QRCodeComponent.tsx index 89f3c546c..72f0a65b1 100644 --- a/components/QRCodeComponent.tsx +++ b/components/QRCodeComponent.tsx @@ -44,8 +44,15 @@ const menuActions: Action[] = text: loc.transactions.details_copy, icon: actionIcons.Copy, }, + { id: actionKeys.Share, text: loc.receive.details_share, icon: actionIcons.Share }, ] - : [{ id: actionKeys.Share, text: loc.receive.details_share, icon: actionIcons.Share }]; + : [ + { + id: actionKeys.Copy, + text: loc.transactions.details_copy, + icon: actionIcons.Copy, + }, + ]; const QRCodeComponent: React.FC = ({ value = '', diff --git a/components/TooltipMenu.ios.tsx b/components/TooltipMenu.ios.tsx index f281ffdb6..90eb89958 100644 --- a/components/TooltipMenu.ios.tsx +++ b/components/TooltipMenu.ios.tsx @@ -16,6 +16,7 @@ const BaseToolTipMenu = (props: ToolTipMenuProps, ref: Ref) => { onMenuWillHide, buttonStyle, onPressMenuItem, + ...restProps } = props; const menuItemMapped = useCallback(({ action, menuOptions }: { action: Action; menuOptions?: string[] }) => { @@ -70,8 +71,12 @@ const BaseToolTipMenu = (props: ToolTipMenuProps, ref: Ref) => { menuTitle: title, menuItems, }} + {...restProps} + style={buttonStyle} > - {props.children} + + {props.children} + ); @@ -98,7 +103,7 @@ const BaseToolTipMenu = (props: ToolTipMenuProps, ref: Ref) => { : {})} > {onPress ? ( - + {props.children} ) : ( @@ -108,7 +113,7 @@ const BaseToolTipMenu = (props: ToolTipMenuProps, ref: Ref) => { ); return isMenuPrimaryAction && onPress ? ( - + {renderContextMenuButton()} ) : isButton ? ( diff --git a/components/types.ts b/components/types.ts index d4a7c623f..95daf757a 100644 --- a/components/types.ts +++ b/components/types.ts @@ -1,4 +1,4 @@ -import { ViewStyle } from 'react-native'; +import { AccessibilityRole, ViewStyle } from 'react-native'; export interface Action { id: string | number; @@ -23,7 +23,12 @@ export interface ToolTipMenuProps { renderPreview?: () => React.ReactNode; onPress?: () => void; previewValue?: string; + accessibilityRole?: AccessibilityRole; disabled?: boolean; + testID?: string; + style?: ViewStyle | ViewStyle[]; + accessibilityLabel?: string; + accessibilityHint?: string; buttonStyle?: ViewStyle; onMenuWillShow?: () => void; onMenuWillHide?: () => void; From 7824f10e360ef2c862492ce8db3aed0ba85654fa Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Sun, 26 May 2024 10:44:50 -0400 Subject: [PATCH 02/18] REF: Use existing nav ref for scanQR helper #6601 --- components/AddressInput.tsx | 7 ++----- helpers/scan-qr.ts | 14 ++++---------- screen/send/Broadcast.tsx | 7 +++---- screen/send/details.tsx | 2 +- screen/send/psbtMultisigQRCode.js | 2 +- screen/settings/electrumSettings.js | 3 +-- screen/wallets/ViewEditMultisigCosigners.tsx | 3 +-- screen/wallets/WalletsList.tsx | 4 ++-- screen/wallets/addMultisigStep2.js | 2 +- screen/wallets/transactions.js | 2 +- 10 files changed, 17 insertions(+), 29 deletions(-) diff --git a/components/AddressInput.tsx b/components/AddressInput.tsx index 846e4fa71..c81f6ba85 100644 --- a/components/AddressInput.tsx +++ b/components/AddressInput.tsx @@ -1,7 +1,5 @@ -import { useNavigation } from '@react-navigation/native'; import React from 'react'; import { Image, Keyboard, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native'; - import { scanQrHelper } from '../helpers/scan-qr'; import loc from '../loc'; import { useTheme } from './themes'; @@ -51,7 +49,6 @@ const AddressInput = ({ keyboardType = 'default', }: AddressInputProps) => { const { colors } = useTheme(); - const { navigate } = useNavigation(); const stylesHook = StyleSheet.create({ root: { borderColor: colors.formBorder, @@ -77,7 +74,7 @@ const AddressInput = ({ case actionKeys.ScanQR: scanButtonTapped(); if (launchedBy) { - scanQrHelper(navigate, launchedBy) + scanQrHelper(launchedBy) .then(value => onBarScanned({ data: value })) .catch(error => { presentAlert({ message: error.message }); @@ -145,7 +142,7 @@ const AddressInput = ({ await scanButtonTapped(); Keyboard.dismiss(); // @ts-ignore: Fix later - scanQrHelper(navigate, launchedBy).then(onBarScanned); + scanQrHelper(launchedBy).then(onBarScanned); }} accessibilityRole="button" style={[styles.scan, stylesHook.scan]} diff --git a/helpers/scan-qr.ts b/helpers/scan-qr.ts index 905c601a7..11cb93333 100644 --- a/helpers/scan-qr.ts +++ b/helpers/scan-qr.ts @@ -1,23 +1,17 @@ import { Platform } from 'react-native'; 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, * and then navigates back. If QRCode scan was closed, promise resolves to null. * - * @param navigateFunc {function} * @param currentScreenName {string} * @param showFileImportButton {boolean} * * @param onDismiss {function} - if camera is closed via X button it gets triggered * @return {Promise} */ -function scanQrHelper( - navigateFunc: (scr: string | any, params?: any) => void, - currentScreenName: string, - showFileImportButton = true, - onDismiss?: () => void, -): Promise { +function scanQrHelper(currentScreenName: string, showFileImportButton = true, onDismiss?: () => void): Promise { return requestCameraAuthorization().then(() => { return new Promise(resolve => { const params = { @@ -28,10 +22,10 @@ function scanQrHelper( params.onBarScanned = function (data: any) { setTimeout(() => resolve(data.data || data), 1); - navigateFunc({ name: currentScreenName, params: {}, merge: true }); + ({ name: currentScreenName, params: {}, merge: true }); }; - navigateFunc('ScanQRCodeRoot', { + navigationRef.navigate('ScanQRCodeRoot', { screen: 'ScanQRCode', params, }); diff --git a/screen/send/Broadcast.tsx b/screen/send/Broadcast.tsx index 849f2b62d..f38e15767 100644 --- a/screen/send/Broadcast.tsx +++ b/screen/send/Broadcast.tsx @@ -1,6 +1,6 @@ -import { useNavigation, useRoute } from '@react-navigation/native'; -import * as bitcoin from 'bitcoinjs-lib'; 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 * as BlueElectrum from '../../blue_modules/BlueElectrum'; @@ -37,7 +37,6 @@ interface SuccessScreenProps { const Broadcast: React.FC = () => { const { name } = useRoute(); - const { navigate } = useNavigation(); const [tx, setTx] = useState(); const [txHex, setTxHex] = useState(); const { colors } = useTheme(); @@ -83,7 +82,7 @@ const Broadcast: React.FC = () => { }; const handleQRScan = async () => { - const scannedData = await scanQrHelper(navigate, name); + const scannedData = await scanQrHelper(name); if (!scannedData) return; if (scannedData.indexOf('+') === -1 && scannedData.indexOf('=') === -1 && scannedData.indexOf('=') === -1) { diff --git a/screen/send/details.tsx b/screen/send/details.tsx index 618df4df5..b78bdf328 100644 --- a/screen/send/details.tsx +++ b/screen/send/details.tsx @@ -857,7 +857,7 @@ const SendDetails = () => { setIsLoading(true); setOptionsVisible(false); 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); let tx; diff --git a/screen/send/psbtMultisigQRCode.js b/screen/send/psbtMultisigQRCode.js index 484dc2561..3377b49e2 100644 --- a/screen/send/psbtMultisigQRCode.js +++ b/screen/send/psbtMultisigQRCode.js @@ -60,7 +60,7 @@ const PsbtMultisigQRCode = () => { }; const openScanner = async () => { - const scanned = await scanQrHelper(navigate, name, true); + const scanned = await scanQrHelper(name, true); onBarScanned({ data: scanned }); }; diff --git a/screen/settings/electrumSettings.js b/screen/settings/electrumSettings.js index 6aa9b887a..93a130328 100644 --- a/screen/settings/electrumSettings.js +++ b/screen/settings/electrumSettings.js @@ -36,7 +36,6 @@ import ListItem from '../../components/ListItem'; import { BlueCurrentTheme } from '../../components/themes'; import { scanQrHelper } from '../../helpers/scan-qr'; import loc from '../../loc'; -import { navigationRef } from '../../NavigationService'; export default class ElectrumSettings extends Component { static contextType = BlueStorageContext; @@ -225,7 +224,7 @@ export default class ElectrumSettings extends Component { }; importScan = async () => { - const scanned = await scanQrHelper(navigationRef.navigate, 'ElectrumSettings', true); + const scanned = await scanQrHelper('ElectrumSettings', true); this.onBarScanned(scanned); }; diff --git a/screen/wallets/ViewEditMultisigCosigners.tsx b/screen/wallets/ViewEditMultisigCosigners.tsx index bcff674cf..3614dc60d 100644 --- a/screen/wallets/ViewEditMultisigCosigners.tsx +++ b/screen/wallets/ViewEditMultisigCosigners.tsx @@ -51,7 +51,6 @@ import { useBiometrics } from '../../hooks/useBiometrics'; import { useExtendedNavigation } from '../../hooks/useExtendedNavigation'; import usePrivacy from '../../hooks/usePrivacy'; import loc from '../../loc'; -import * as NavigationService from '../../NavigationService'; import ActionSheet from '../ActionSheet'; const ViewEditMultisigCosigners: React.FC = () => { @@ -513,7 +512,7 @@ const ViewEditMultisigCosigners: React.FC = () => { const scanOrOpenFile = async () => { setIsProvideMnemonicsModalVisible(false); - const scanned = await scanQrHelper(NavigationService.navigate, route.name, true); + const scanned = await scanQrHelper(route.name, true); setImportText(String(scanned)); setIsProvideMnemonicsModalVisible(true); }; diff --git a/screen/wallets/WalletsList.tsx b/screen/wallets/WalletsList.tsx index 4488511aa..679fc159f 100644 --- a/screen/wallets/WalletsList.tsx +++ b/screen/wallets/WalletsList.tsx @@ -318,7 +318,7 @@ const WalletsList: React.FC = () => { }; const onScanButtonPressed = () => { - scanQrHelper(navigate, routeName).then(onBarScanned); + scanQrHelper(routeName).then(onBarScanned); }; const onBarScanned = (value: any) => { @@ -364,7 +364,7 @@ const WalletsList: React.FC = () => { }); break; case 2: - scanQrHelper(navigate, routeName, true).then(data => onBarScanned(data)); + scanQrHelper(routeName, true).then(data => onBarScanned(data)); break; case 3: if (!isClipboardEmpty) { diff --git a/screen/wallets/addMultisigStep2.js b/screen/wallets/addMultisigStep2.js index e5916b8d6..3e2211966 100644 --- a/screen/wallets/addMultisigStep2.js +++ b/screen/wallets/addMultisigStep2.js @@ -461,7 +461,7 @@ const WalletsAddMultisigStep2 = () => { const scanOrOpenFile = () => { setIsProvideMnemonicsModalVisible(false); InteractionManager.runAfterInteractions(async () => { - const scanned = await scanQrHelper(navigation.navigate, name, true); + const scanned = await scanQrHelper(name, true); onBarScanned({ data: scanned }); }); }; diff --git a/screen/wallets/transactions.js b/screen/wallets/transactions.js index 4f779563f..eacb9dff3 100644 --- a/screen/wallets/transactions.js +++ b/screen/wallets/transactions.js @@ -409,7 +409,7 @@ const WalletTransactions = ({ navigation }) => { choosePhoto(); break; case 2: - scanQrHelper(navigate, name, true).then(data => onBarCodeRead(data)); + scanQrHelper(name, true).then(data => onBarCodeRead(data)); break; case 3: if (!isClipboardEmpty) { From b73a6eb232f4d128c94ef730672c3248d158f411 Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Sun, 26 May 2024 10:51:09 -0400 Subject: [PATCH 03/18] Update scan-qr.ts --- helpers/scan-qr.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers/scan-qr.ts b/helpers/scan-qr.ts index 11cb93333..fafdf0334 100644 --- a/helpers/scan-qr.ts +++ b/helpers/scan-qr.ts @@ -22,7 +22,7 @@ function scanQrHelper(currentScreenName: string, showFileImportButton = true, on params.onBarScanned = function (data: any) { setTimeout(() => resolve(data.data || data), 1); - ({ name: currentScreenName, params: {}, merge: true }); + navigationRef.navigate({ name: currentScreenName, params: {}, merge: true }); }; navigationRef.navigate('ScanQRCodeRoot', { From feeaf65aa072d10a7dd661a3283b3d54fd6c12e1 Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Sun, 26 May 2024 17:07:26 +0000 Subject: [PATCH 04/18] Translate loc/en.json in de_DE 100% reviewed source file: 'loc/en.json' on 'de_DE'. --- loc/de_de.json | 53 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/loc/de_de.json b/loc/de_de.json index c1c580066..f8aa2528d 100644 --- a/loc/de_de.json +++ b/loc/de_de.json @@ -120,11 +120,13 @@ "details_create": "Erstelle", "details_label": "Beschreibung", "details_setAmount": "Zu erhaltender Betrag", + "details_share": "Teilen", "header": "Erhalten", "maxSats": "Der größtmögliche Betrag ist {max} sats", "maxSatsFull": "Der größtmögliche Betrag ist {max} sats oder {currency}", "minSats": "Der kleinstmögliche Betrag ist {min} sats", - "minSatsFull": "Der kleinstmögliche Betrag ist {min} sats oder {currency}" + "minSatsFull": "Der kleinstmögliche Betrag ist {min} sats oder {currency}", + "qrcode_for_the_address": "QR-Code für die Adresse" }, "send": { "provided_address_is_invoice": "Diese Adresse ist für eine Lightning-Rechnung. Um diese Rechnung zu zahlen ist ein Lightning Wallet zu verwenden.", @@ -165,6 +167,7 @@ "details_next": "Weiter", "details_no_signed_tx": "Die ausgewählte Datei enthält keine importierbare signierte Transaktion.", "details_note_placeholder": "Eigene Bezeichnung", + "counterparty_label_placeholder": "Kontaktnamen bearbeiten", "details_scan": "Scannen", "details_scan_hint": "Zum Importieren / Scannen zweimal tippen", "details_total_exceeds_balance": "Der zu sendende Betrag ist größer als der verfügbare Betrag.", @@ -209,6 +212,7 @@ "reset_amount_confirm": "Möchten Du den Betrag zurücksetzen?", "success_done": "Fertig", "txSaved": "Die Transaktionsdatei ({filePath}) wurde im Download-Ordner gespeichert.", + "file_saved_at_path": "Die Datei ({fileName}) wurde im Download-Ordner gespeichert.", "problem_with_psbt": "PSBT-Problem" }, "settings": { @@ -273,7 +277,9 @@ "encrypt_title": "Sicherheit", "encrypt_tstorage": "Speicher", "encrypt_use": "Benutze {type}", + "encrypted_feature_disabled": "Diese Funktion kann bei verschlüsseltem Speicher nicht genutzt werden.", "encrypt_use_expl": "{type} wird zur Transaktionsdurchführung, zum Entsperren, dem Export oder der Löschung einer Wallet benötigt. {type} ersetzt nicht die Passworteingabe bei verschlüsseltem Speicher.", + "biometrics_fail": "Wenn {type} nicht aktiviert ist oder entsperrt werden kann, alternativ Ihren Gerätepasscode verwenden.", "general": "Allgemein", "general_adv_mode": "Erweiterter Modus", "general_adv_mode_e": "Erlaubt, wenn aktiviert, verschiedene Wallet-Typen anzulegen, dabei eine benutzerdefinierte Entropie zu verwenden und die LNDHub-Instanz der Lightning Wallet frei zu definieren.", @@ -284,6 +290,7 @@ "language": "Sprache", "last_updated": "Zuletzt aktualisiert", "language_isRTL": "BlueWallet zur Aktivierung der Änderung der Schriftrichtung neu starten.", + "license": "Lizenz", "lightning_error_lndhub_uri": "Keine gültige LndHub URI", "lightning_saved": "Deine Änderungen wurden gespeichert.", "lightning_settings": "Lightning-Einstellungen", @@ -336,7 +343,6 @@ "cpfp_title": "TRX-Gebühr erhöhen (CPFP)", "details_balance_hide": "Guthaben verbergen", "details_balance_show": "Guthaben zeigen", - "details_block": "Blockhöhe", "details_copy": "Kopieren", "details_copy_amount": "Betrag kopieren", "details_copy_block_explorer_link": "Block-Explorer Link kopieren", @@ -347,7 +353,7 @@ "details_outputs": "Ausgänge", "date": "Datum", "details_received": "Empfangen", - "transaction_note_saved": "Transaktionsbezeichnung erfolgreich gespeichert.", + "transaction_saved": "Gespeichert", "details_show_in_block_explorer": "Im Block-Explorer zeigen", "details_title": "Transaktion", "details_to": "Ausgang", @@ -368,6 +374,8 @@ "status_cancel": "Transaktion abbrechen", "transactions_count": "Anzahl Transaktionen", "txid": "Transaktions-ID", + "from": "Von: {counterparty}", + "to": "Zu: {counterparty}", "updating": "Aktualisiere...." }, "wallets": { @@ -398,6 +406,7 @@ "details_delete": "Löschen", "details_delete_wallet": "Wallet löschen", "details_derivation_path": "Ableitungspfad", + "details_display": "Auf der Startseite anzeigen", "details_export_backup": "Exportieren / Backup", "details_export_history": "Verlauf als CSV exportieren", "details_master_fingerprint": "Fingerabdruckkennung", @@ -444,9 +453,9 @@ "list_empty_txs2": "Beginne mit deinem Wallet.", "list_empty_txs2_lightning": "\nDrücke zum Starten «Beträge verwalten», um das Wallet aufzuladen.", "list_latest_transaction": "Letzte Transaktion", - "list_ln_browser": "LApp Browser", "list_long_choose": "Foto auswählen", "list_long_clipboard": "Aus der Zwischenablage kopieren", + "import_file": "Datei importieren", "list_long_scan": "QR Code scannen", "list_title": "Wallets", "list_tryagain": "Nochmal versuchen", @@ -462,7 +471,8 @@ "warning_do_not_disclose": "Warnung! Nicht veröffentlichen", "add_ln_wallet_first": "Bitte zuerst ein Lightning-Wallet hinzufügen.", "identity_pubkey": "Pubkey-Identität", - "xpub_title": "Wallet xPub" + "xpub_title": "Wallet xPub", + "search_wallets": "Wallets suchen" }, "multisig": { "multisig_vault": "Tresor", @@ -475,7 +485,10 @@ "fee_btc": "{number} BTC", "confirm": "Bestätigen", "header": "Senden", + "share": "Teilen", "view": "Anzeigen", + "shared_key_detected": "Geteilte Mitsignierer", + "shared_key_detected_question": "Ein Mitsignierer wurde mit Ihnen geteilt. Diesen jetzt importierten?", "manage_keys": "Schlüssel verwalten", "how_many_signatures_can_bluewallet_make": "Anzahl Signaturen durch BlueWallet", "signatures_required_to_spend": "Benötigte Signaturen {number}", @@ -510,6 +523,7 @@ "i_have_mnemonics": "Seed des Schlüssels importieren", "type_your_mnemonics": "Seed zum Import deines Tresorschlüssels eingeben", "this_is_cosigners_xpub": "Dies ist der xPub für Mitsigierer zum Import in ein anderes Wallet. Er kann sicher mit anderen geteilt werden.", + "this_is_cosigners_xpub_airdrop": "Zur AirDrop-Freigabe müssen alle Empfänger auf dem Koordinierungsbildschirm sein.", "wallet_key_created": "Dein Tresorschlüssel wurde erstellt. Nimm dir Zeit ein sicheres Backup des mnemonischen Seeds herzustellen. ", "are_you_sure_seed_will_be_lost": "Bist du sicher? Dein mnemonischer Seed ist ohne Backup verloren!", "forget_this_seed": "Seed vergessen und xPub verwenden.", @@ -542,6 +556,12 @@ "no_wallet_owns_address": "Keines der verfügbaren Wallet besitzt die eingegebene Adresse.", "view_qrcode": "QR-Code anzeigen" }, + "autofill_word": { + "title": "Das letzte mnemonische Wort generieren", + "enter": "Die unvollendete mnemonische Phrase eingeben", + "generate_word": "Erzeuge das letzte Word", + "error": "Die Eingabe ist keine unvollendete 11- oder 23 Wort Phrase. Bitte erneut versuchen." + }, "cc": { "change": "Ändern", "coins_selected": "Anz. gewählte Münzen ({number})", @@ -562,6 +582,8 @@ "sats": "sats" }, "addresses": { + "copy_private_key": "Privaten Schlüssel kopieren", + "sensitive_private_key": "Warnung: Private Schlüssel sind gefahrvoll. Weiterfahren?", "sign_title": "Meldung signieren/verifizieren", "sign_help": "Auf einer Bitcoin-Adresse basierende, kryptografische Signatur erstellen oder verifizieren.", "sign_sign": "Signieren", @@ -594,10 +616,23 @@ "authenticate": "Authentifizieren" }, "bip47": { - "payment_code": "Bezahlcode", - "payment_codes_list": "Bezahlcodeliste", - "who_can_pay_me": "Wer kann mich bezahlen:", + "payment_code": "Zahlungscode", + "contacts": "Kontakte", "purpose": "Wiederverwendbarer und teilbarer Code (BIP47)", - "not_found": "Bezahlcode nicht gefunden" + "pay_this_contact": "An diesen Kontakt zahlen", + "rename_contact": "Kontakt umbenennen", + "copy_payment_code": "Zahlungscode kopieren", + "copied": "Kopiert", + "rename": "Umbenennen", + "provide_name": "Neuer Kontaktnahme eingeben", + "add_contact": "Kontakt hinzufügen", + "provide_payment_code": "Zahlungscode eingeben", + "invalid_pc": "Ungültiger Zahlungscode", + "notification_tx_unconfirmed": "Benachrichtigungstransaktion noch unbestätigt. Bitte warten", + "failed_create_notif_tx": "On-Chain Transaktion konnte nicht in erstellt werden", + "onchain_tx_needed": "On-Chain Transaktion benötigt.", + "notif_tx_sent" : "Benachrichtigungstransaktion ist gesendet. Auf Bestätigung warten.", + "notif_tx": "Benachrichtigungstransaktion", + "not_found": "Zahlungscode nicht gefunden" } } From acb00a8afe4528cfcbe03bc5a1324e9e792d58cd Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Sun, 26 May 2024 17:30:58 +0000 Subject: [PATCH 05/18] Translate name.txt in de_DE 100% reviewed source file: 'name.txt' on 'de_DE'. --- ios/fastlane/metadata/de-DE/name.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/fastlane/metadata/de-DE/name.txt b/ios/fastlane/metadata/de-DE/name.txt index f6df796ef..265118bec 100644 --- a/ios/fastlane/metadata/de-DE/name.txt +++ b/ios/fastlane/metadata/de-DE/name.txt @@ -1 +1 @@ -BlueWallet - Bitcoin Wallet \ No newline at end of file +BlueWallet - Bitcoin Wallet From 07f07d3d38f364f69b890ee34adc599910175c36 Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Sun, 26 May 2024 18:10:38 -0400 Subject: [PATCH 06/18] FIX: Notes were not persistent --- blue_modules/storage-context.tsx | 6 ++++-- components/HeaderRightButton.tsx | 3 ++- navigation/DetailViewScreensStack.tsx | 2 +- .../{details.tsx => TransactionDetails.tsx} | 11 +++++++++-- 4 files changed, 16 insertions(+), 6 deletions(-) rename screen/transactions/{details.tsx => TransactionDetails.tsx} (98%) diff --git a/blue_modules/storage-context.tsx b/blue_modules/storage-context.tsx index 53aa71c1a..5940a751d 100644 --- a/blue_modules/storage-context.tsx +++ b/blue_modules/storage-context.tsx @@ -63,8 +63,8 @@ export enum WalletTransactionsStatus { // @ts-ignore defaut value does not match the type export const BlueStorageContext = createContext(undefined); export const BlueStorageProvider = ({ children }: { children: React.ReactNode }) => { - const txMetadata = useRef(BlueApp.tx_metadata); - const counterpartyMetadata = useRef(BlueApp.counterparty_metadata || {}); // init + const txMetadata = useRef({}); + const counterpartyMetadata = useRef({}); // init const getTransactions = BlueApp.getTransactions; const fetchWalletBalances = BlueApp.fetchWalletBalances; const fetchWalletTransactions = BlueApp.fetchWalletTransactions; @@ -94,6 +94,8 @@ export const BlueStorageProvider = ({ children }: { children: React.ReactNode }) BlueElectrum.isDisabled().then(setIsElectrumDisabled); if (walletsInitialized) { setWallets(BlueApp.getWallets()); + txMetadata.current = BlueApp.tx_metadata; + counterpartyMetadata.current = BlueApp.counterparty_metadata; BlueElectrum.connectMain(); } }, [walletsInitialized]); diff --git a/components/HeaderRightButton.tsx b/components/HeaderRightButton.tsx index 9d8759ee9..f02f5fcdb 100644 --- a/components/HeaderRightButton.tsx +++ b/components/HeaderRightButton.tsx @@ -12,11 +12,12 @@ interface HeaderRightButtonProps { const HeaderRightButton: React.FC = ({ disabled = true, onPress, title, testID }) => { const { colors } = useTheme(); + const opacity = disabled ? 0.5 : 1; return ( diff --git a/navigation/DetailViewScreensStack.tsx b/navigation/DetailViewScreensStack.tsx index 34156f1c9..610508fc8 100644 --- a/navigation/DetailViewScreensStack.tsx +++ b/navigation/DetailViewScreensStack.tsx @@ -21,7 +21,7 @@ import Broadcast from '../screen/send/Broadcast'; import IsItMyAddress from '../screen/send/isItMyAddress'; import Success from '../screen/send/success'; import CPFP from '../screen/transactions/CPFP'; -import TransactionDetails from '../screen/transactions/details'; +import TransactionDetails from '../screen/transactions/TransactionDetails'; import RBFBumpFee from '../screen/transactions/RBFBumpFee'; import RBFCancel from '../screen/transactions/RBFCancel'; import TransactionStatus from '../screen/transactions/TransactionStatus'; diff --git a/screen/transactions/details.tsx b/screen/transactions/TransactionDetails.tsx similarity index 98% rename from screen/transactions/details.tsx rename to screen/transactions/TransactionDetails.tsx index 440a62ec4..60073c8f0 100644 --- a/screen/transactions/details.tsx +++ b/screen/transactions/TransactionDetails.tsx @@ -103,9 +103,16 @@ const TransactionDetails = () => { }, [tx, txMetadata, memo, counterpartyLabel, paymentCode, saveToDisk, counterpartyMetadata]); const HeaderRight = useMemo( - () => , + () => + tx && ( + + ), - [isLoading, handleOnSaveButtonTapped], + [tx, txMetadata, memo, handleOnSaveButtonTapped], ); useEffect(() => { From 3b9accc2db5c51e8c62fa5443a297d436d7c2028 Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Sun, 26 May 2024 18:20:27 -0400 Subject: [PATCH 07/18] Update AddressInput.tsx --- components/AddressInput.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/AddressInput.tsx b/components/AddressInput.tsx index 3d0489d35..b12f8e36f 100644 --- a/components/AddressInput.tsx +++ b/components/AddressInput.tsx @@ -144,8 +144,7 @@ const AddressInput = ({ onPress={async () => { await scanButtonTapped(); Keyboard.dismiss(); - // @ts-ignore: Fix later - scanQrHelper(navigate, launchedBy).then(onBarScanned); + if (launchedBy) scanQrHelper(launchedBy).then(value => onBarScanned({ data: value })); }} style={[styles.scan, stylesHook.scan]} accessibilityLabel={loc.send.details_scan} From d9c913c265b7b257c4ba01eaffa387bd41d06128 Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Sun, 26 May 2024 18:58:43 -0400 Subject: [PATCH 08/18] Update storage-context.tsx --- blue_modules/storage-context.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/blue_modules/storage-context.tsx b/blue_modules/storage-context.tsx index 5940a751d..b6ac8156f 100644 --- a/blue_modules/storage-context.tsx +++ b/blue_modules/storage-context.tsx @@ -63,8 +63,8 @@ export enum WalletTransactionsStatus { // @ts-ignore defaut value does not match the type export const BlueStorageContext = createContext(undefined); export const BlueStorageProvider = ({ children }: { children: React.ReactNode }) => { - const txMetadata = useRef({}); - const counterpartyMetadata = useRef({}); // init + const txMetadata = useRef(BlueApp.tx_metadata); + const counterpartyMetadata = useRef(BlueApp.counterparty_metadata || {}); // init const getTransactions = BlueApp.getTransactions; const fetchWalletBalances = BlueApp.fetchWalletBalances; const fetchWalletTransactions = BlueApp.fetchWalletTransactions; @@ -93,9 +93,9 @@ export const BlueStorageProvider = ({ children }: { children: React.ReactNode }) useEffect(() => { BlueElectrum.isDisabled().then(setIsElectrumDisabled); if (walletsInitialized) { - setWallets(BlueApp.getWallets()); txMetadata.current = BlueApp.tx_metadata; counterpartyMetadata.current = BlueApp.counterparty_metadata; + setWallets(BlueApp.getWallets()); BlueElectrum.connectMain(); } }, [walletsInitialized]); From 31ebd5ea1bfbe13710d239195982acd030415fc0 Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Sun, 26 May 2024 19:24:42 -0400 Subject: [PATCH 09/18] REF: Use a single navigator stack instead of 2 and abandoning 1 --- navigation/DetailViewScreensStack.tsx | 126 +++++++++++++------------ navigation/DetailViewStackParamList.ts | 1 + navigation/index.tsx | 11 ++- 3 files changed, 73 insertions(+), 65 deletions(-) diff --git a/navigation/DetailViewScreensStack.tsx b/navigation/DetailViewScreensStack.tsx index 34156f1c9..d1a085990 100644 --- a/navigation/DetailViewScreensStack.tsx +++ b/navigation/DetailViewScreensStack.tsx @@ -1,5 +1,4 @@ -import { StackActions } from '@react-navigation/native'; -import { NativeStackNavigationOptions, createNativeStackNavigator } from '@react-navigation/native-stack'; +import { NativeStackNavigationOptions } from '@react-navigation/native-stack'; import React, { useMemo } from 'react'; import { I18nManager, Platform, TouchableOpacity } from 'react-native'; import { Icon } from 'react-native-elements'; @@ -32,7 +31,13 @@ import LdkViewLogs from '../screen/wallets/ldkViewLogs'; import SelectWallet from '../screen/wallets/selectWallet'; import WalletTransactions from '../screen/wallets/transactions'; import WalletsList from '../screen/wallets/WalletsList'; -import { NavigationDefaultOptions, NavigationDefaultOptionsForDesktop, NavigationFormModalOptions, StatusBarLightOptions } from './'; +import { + NavigationDefaultOptions, + NavigationDefaultOptionsForDesktop, + NavigationFormModalOptions, + StatusBarLightOptions, + DetailViewStack, +} from './index'; // Importing the navigator import AddWalletStack from './AddWalletStack'; import AztecoRedeemStackRoot from './AztecoRedeemStack'; import ExportMultisigCoordinationSetupStackRoot from './ExportMultisigCoordinationSetupStack'; @@ -67,9 +72,8 @@ import SignVerifyStackRoot from './SignVerifyStack'; import ViewEditMultisigCosignersStackRoot from './ViewEditMultisigCosignersStack'; import WalletExportStack from './WalletExportStack'; import WalletXpubStackRoot from './WalletXpubStack'; -import { DetailViewStackParamList } from './DetailViewStackParamList'; +import { StackActions } from '@react-navigation/native'; -const DetailViewRoot = createNativeStackNavigator(); const DetailViewStackScreensStack = () => { const theme = useTheme(); const navigation = useExtendedNavigation(); @@ -107,17 +111,17 @@ const DetailViewStackScreensStack = () => { const walletListScreenOptions = useWalletListScreenOptions; return ( - - - + - { closeButtonFunc: popToTop, })(theme)} /> - - + { headerRight: () => SaveButton, })(theme)} /> - - + - { headerRight: () => SaveButton, })(theme)} /> - - - + + + - - { }, })(theme)} /> - - - - - - + + { closeButtonFunc: popToTop, })(theme)} /> - { closeButtonFunc: popToTop, })(theme)} /> - - + { gestureEnabled: false, }} /> - + - - + - - - + + + {/* screens */} - - - { animationTypeForReplace: 'push', })(theme)} /> - - - - - - - + - - - - - - - - - + - - - - - + { }} /> - - + { presentation: 'modal', }} /> - + ); }; diff --git a/navigation/DetailViewStackParamList.ts b/navigation/DetailViewStackParamList.ts index 86688233a..839f232ed 100644 --- a/navigation/DetailViewStackParamList.ts +++ b/navigation/DetailViewStackParamList.ts @@ -1,4 +1,5 @@ export type DetailViewStackParamList = { + UnlockWithScreen: undefined; WalletsList: undefined; WalletTransactions: { walletID: string; walletType: string }; LDKOpenChannelRoot: undefined; diff --git a/navigation/index.tsx b/navigation/index.tsx index 6c194596a..f9d3d872c 100644 --- a/navigation/index.tsx +++ b/navigation/index.tsx @@ -5,6 +5,7 @@ import { isHandset } from '../blue_modules/environment'; import { useStorage } from '../blue_modules/storage-context'; import UnlockWith from '../screen/UnlockWith'; import { LazyLoadingIndicator } from './LazyLoadingIndicator'; +import { DetailViewStackParamList } from './DetailViewStackParamList'; const DetailViewScreensStack = lazy(() => import('./DetailViewScreensStack')); const DrawerRoot = lazy(() => import('./DrawerRoot')); @@ -21,15 +22,16 @@ export const NavigationFormModalOptions: NativeStackNavigationOptions = { export const NavigationDefaultOptionsForDesktop: NativeStackNavigationOptions = { headerShown: false, presentation: 'fullScreenModal' }; export const StatusBarLightOptions: NativeStackNavigationOptions = { statusBarStyle: 'light' }; -const UnlockStack = createNativeStackNavigator(); +const DetailViewStack = createNativeStackNavigator(); const UnlockRoot = () => { return ( - - - + + + ); }; + const MainRoot = () => { const { walletsInitialized } = useStorage(); @@ -51,3 +53,4 @@ const MainRoot = () => { }; export default MainRoot; +export { DetailViewStack }; // Exporting the navigator to use it in DetailViewScreensStack From 88d25df7f12b925fed26523edc2f8846996fb0ad Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Sun, 26 May 2024 21:14:21 -0400 Subject: [PATCH 10/18] ADD: GHS and XAF --- models/fiatUnits.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/models/fiatUnits.json b/models/fiatUnits.json index 332035aa0..c14837051 100644 --- a/models/fiatUnits.json +++ b/models/fiatUnits.json @@ -384,11 +384,25 @@ "symbol": "Bs.", "country": "Venezuela (Venezuelan Bolívar Soberano)" }, + "XAF": { + "endPointKey": "XAF", + "locale": "fr-CF", + "source": "CoinDesk", + "symbol": "Fr", + "country": "Central African Republic (Central African Franc)" + }, "ZAR": { "endPointKey": "ZAR", "locale": "en-ZA", "source": "CoinGecko", "symbol": "R", "country": "South Africa (South African Rand)" + }, + "GHS": { + "endPointKey": "GHS", + "locale": "en-GH", + "source": "CoinDesk", + "symbol": "₵", + "country": "Ghana (Ghanaian Cedi)" } } From b4468faa8523d96b252cee48a7ad5be320112aea Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Sun, 26 May 2024 21:20:31 -0400 Subject: [PATCH 11/18] Update Currency.tsx --- screen/settings/Currency.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/screen/settings/Currency.tsx b/screen/settings/Currency.tsx index 1461642ea..5bfa90694 100644 --- a/screen/settings/Currency.tsx +++ b/screen/settings/Currency.tsx @@ -24,7 +24,7 @@ dayjs.extend(calendar); const Currency: React.FC = () => { const { setPreferredFiatCurrencyStorage } = useSettings(); - const [isSavingNewPreferredCurrency, setIsSavingNewPreferredCurrency] = useState(false); + const [isSavingNewPreferredCurrency, setIsSavingNewPreferredCurrency] = useState(); const [selectedCurrency, setSelectedCurrency] = useState(FiatUnit.USD); const [currencyRate, setCurrencyRate] = useState({ LastUpdated: null, Rate: null }); const [isSearchFocused, setIsSearchFocused] = useState(false); @@ -80,13 +80,14 @@ const Currency: React.FC = () => { const renderItem = ({ item }: { item: FiatUnitType }) => ( { - setIsSavingNewPreferredCurrency(true); + setIsSavingNewPreferredCurrency(item); try { await getFiatRate(item.endPointKey); await setPreferredCurrency(item); @@ -100,7 +101,7 @@ const Currency: React.FC = () => { message: error.message ? `${loc.settings.currency_fetch_error}: ${error.message}` : loc.settings.currency_fetch_error, }); } finally { - setIsSavingNewPreferredCurrency(false); + setIsSavingNewPreferredCurrency(undefined); } }} /> From ebb3ddac5bc9a7f58ba43b91cd94b9e249456f14 Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Sun, 26 May 2024 22:03:35 -0400 Subject: [PATCH 12/18] FIX: Removed some ts-ignores --- components/ListItem.tsx | 3 +- components/TransactionListItem.tsx | 23 +++---- components/TransactionsNavigationHeader.tsx | 14 ++--- components/addresses/AddressItem.tsx | 56 +++++++++-------- components/types.ts | 1 + navigation/DetailViewScreensStack.tsx | 13 ---- navigation/DetailViewStackParamList.ts | 64 ++++++++++++++------ screen/settings/lightningSettings.tsx | 23 +++---- screen/transactions/details.tsx | 9 ++- screen/wallets/ViewEditMultisigCosigners.tsx | 16 ++--- 10 files changed, 114 insertions(+), 108 deletions(-) diff --git a/components/ListItem.tsx b/components/ListItem.tsx index f68ed980a..2f88d4541 100644 --- a/components/ListItem.tsx +++ b/components/ListItem.tsx @@ -7,7 +7,7 @@ import { useTheme } from './themes'; // Update the type for the props interface ListItemProps { rightIcon?: any; - leftAvatar?: React.Component; + leftAvatar?: React.JSX.Element; containerStyle?: object; Component?: typeof React.Component | typeof PressableWrapper; bottomDivider?: boolean; @@ -27,6 +27,7 @@ interface ListItemProps { isLoading?: boolean; chevron?: boolean; checkmark?: boolean; + subtitleProps?: object; } export class PressableWrapper extends React.Component { diff --git a/components/TransactionListItem.tsx b/components/TransactionListItem.tsx index 453f55948..01f87162a 100644 --- a/components/TransactionListItem.tsx +++ b/components/TransactionListItem.tsx @@ -1,9 +1,7 @@ +import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; import AsyncStorage from '@react-native-async-storage/async-storage'; import Clipboard from '@react-native-clipboard/clipboard'; -import { useNavigation } from '@react-navigation/native'; -import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; import { Linking, StyleSheet, View } from 'react-native'; - import { BlueStorageContext } from '../blue_modules/storage-context'; import Lnurl from '../class/lnurl'; import { LightningTransaction, Transaction } from '../class/wallets/types'; @@ -16,12 +14,14 @@ import TransactionOutgoingIcon from '../components/icons/TransactionOutgoingIcon import TransactionPendingIcon from '../components/icons/TransactionPendingIcon'; import loc, { formatBalanceWithoutSuffix, transactionTimeToReadable } from '../loc'; import { BitcoinUnit } from '../models/bitcoinUnits'; -import * as NavigationService from '../NavigationService'; import { useSettings } from './Context/SettingsContext'; import ListItem from './ListItem'; import { useTheme } from './themes'; import ToolTipMenu from './TooltipMenu'; -import { Action } from './types'; +import { Action, ToolTipMenuProps } from './types'; +import { useExtendedNavigation } from '../hooks/useExtendedNavigation'; +import { NativeStackNavigationProp } from '@react-navigation/native-stack'; +import { DetailViewStackParamList } from '../navigation/DetailViewStackParamList'; interface TransactionListItemProps { itemPriceUnit: BitcoinUnit; @@ -29,11 +29,13 @@ interface TransactionListItemProps { item: Transaction & LightningTransaction; // using type intersection to have less issues with ts } +type NavigationProps = NativeStackNavigationProp; + export const TransactionListItem: React.FC = React.memo(({ item, itemPriceUnit = BitcoinUnit.BTC, walletID }) => { const [subtitleNumberOfLines, setSubtitleNumberOfLines] = useState(1); const { colors } = useTheme(); - const { navigate } = useNavigation(); - const menuRef = useRef(); + const { navigate } = useExtendedNavigation(); + const menuRef = useRef(); const { txMetadata, counterpartyMetadata, wallets } = useContext(BlueStorageContext); const { preferredFiatCurrency, language } = useSettings(); const containerStyle = useMemo( @@ -200,10 +202,8 @@ export const TransactionListItem: React.FC = React.mem }, [subtitle]); const onPress = useCallback(async () => { - // @ts-ignore: idk how to fix menuRef?.current?.dismissMenu?.(); if (item.hash) { - // @ts-ignore: idk how to fix navigate('TransactionStatus', { hash: item.hash, walletID }); } else if (item.type === 'user_invoice' || item.type === 'payment_request' || item.type === 'paid_invoice') { const lightningWallet = wallets.filter(wallet => wallet?.getID() === item.walletID); @@ -217,8 +217,7 @@ export const TransactionListItem: React.FC = React.mem } const loaded = await LN.loadSuccessfulPayment(paymentHash); if (loaded) { - NavigationService.navigate('ScanLndInvoiceRoot', { - // @ts-ignore: idk how to fix + navigate('ScanLndInvoiceRoot', { screen: 'LnurlPaySuccess', params: { paymentHash, @@ -232,7 +231,6 @@ export const TransactionListItem: React.FC = React.mem console.log(e); } - // @ts-ignore: idk how to fix navigate('LNDViewInvoice', { invoice: item, walletID: lightningWallet[0].getID(), @@ -347,7 +345,6 @@ export const TransactionListItem: React.FC = React.mem = ({ - // @ts-ignore: Ugh wallet: initialWallet, - // @ts-ignore: Ugh onWalletUnitChange, - // @ts-ignore: Ugh navigation, - // @ts-ignore: Ugh onManageFundsPressed, - // @ts-ignore: Ugh onWalletBalanceVisibilityChange, }) => { const [wallet, setWallet] = useState(initialWallet); const [allowOnchainAddress, setAllowOnchainAddress] = useState(false); const { preferredFiatCurrency } = useSettings(); - const menuRef = useRef(null); + const menuRef = useRef(null); const verifyIfWalletAllowsOnchainAddress = useCallback(() => { if (wallet.type === LightningCustodianWallet.type) { @@ -85,8 +81,9 @@ const TransactionsNavigationHeader: React.FC }; const changeWalletBalanceUnit = () => { - // @ts-ignore: Ugh - menuRef.current?.dismissMenu(); + if (menuRef.current?.dismissMenu) { + menuRef.current.dismissMenu(); + } let newWalletPreferredUnit = wallet.getPreferredBalanceUnit(); if (newWalletPreferredUnit === BitcoinUnit.BTC) { @@ -140,7 +137,6 @@ const TransactionsNavigationHeader: React.FC ; + const AddressItem = ({ item, balanceUnit, walletID, allowSignVerifyMessage }: AddressItemProps) => { const { wallets } = useStorage(); const { colors } = useTheme(); @@ -52,13 +55,18 @@ const AddressItem = ({ item, balanceUnit, walletID, allowSignVerifyMessage }: Ad }, }); - const { navigate } = useNavigation(); + const { navigate } = useNavigation(); + + const menuRef = useRef(); + + const dismissMenu = () => { + if (menuRef.current?.dismissMenu) { + menuRef.current.dismissMenu(); + } + }; - const menuRef = useRef(); const navigateToReceive = () => { - // @ts-ignore wtf - menuRef.current?.dismissMenu(); - // @ts-ignore wtf + dismissMenu(); navigate('ReceiveDetailsRoot', { screen: 'ReceiveDetails', params: { @@ -69,9 +77,7 @@ const AddressItem = ({ item, balanceUnit, walletID, allowSignVerifyMessage }: Ad }; const navigateToSignVerify = () => { - // @ts-ignore wtf - menuRef.current?.dismissMenu(); - // @ts-ignore wtf + dismissMenu(); navigate('SignVerifyRoot', { screen: 'SignVerify', params: { @@ -114,13 +120,13 @@ const AddressItem = ({ item, balanceUnit, walletID, allowSignVerifyMessage }: Ad }; const onToolTipPress = async (id: string) => { - if (id === AddressItem.actionKeys.CopyToClipboard) { + if (id === actionKeys.CopyToClipboard) { handleCopyPress(); - } else if (id === AddressItem.actionKeys.Share) { + } else if (id === actionKeys.Share) { handleSharePress(); - } else if (id === AddressItem.actionKeys.SignVerify) { + } else if (id === actionKeys.SignVerify) { navigateToSignVerify(); - } else if (id === AddressItem.actionKeys.ExportPrivateKey) { + } else if (id === actionKeys.ExportPrivateKey) { if (await confirm(loc.addresses.sensitive_private_key)) { if (await isBiometricUseCapableAndEnabled()) { if (!(await unlockWithBiometrics())) { @@ -171,14 +177,14 @@ const AddressItem = ({ item, balanceUnit, walletID, allowSignVerifyMessage }: Ad return render(); }; -AddressItem.actionKeys = { +const actionKeys = { Share: 'share', CopyToClipboard: 'copyToClipboard', SignVerify: 'signVerify', ExportPrivateKey: 'exportPrivateKey', }; -AddressItem.actionIcons = { +const actionIcons = { Signature: { iconType: 'SYSTEM', iconValue: 'signature', @@ -220,30 +226,30 @@ const styles = StyleSheet.create({ const getAvailableActions = ({ allowSignVerifyMessage }: { allowSignVerifyMessage: boolean }): Action[] | Action[][] => { const actions = [ { - id: AddressItem.actionKeys.CopyToClipboard, + id: actionKeys.CopyToClipboard, text: loc.transactions.details_copy, - icon: AddressItem.actionIcons.Clipboard, + icon: actionIcons.Clipboard, }, { - id: AddressItem.actionKeys.Share, + id: actionKeys.Share, text: loc.receive.details_share, - icon: AddressItem.actionIcons.Share, + icon: actionIcons.Share, }, ]; if (allowSignVerifyMessage) { actions.push({ - id: AddressItem.actionKeys.SignVerify, + id: actionKeys.SignVerify, text: loc.addresses.sign_title, - icon: AddressItem.actionIcons.Signature, + icon: actionIcons.Signature, }); } if (allowSignVerifyMessage) { actions.push({ - id: AddressItem.actionKeys.ExportPrivateKey, + id: actionKeys.ExportPrivateKey, text: loc.addresses.copy_private_key, - icon: AddressItem.actionIcons.ExportPrivateKey, + icon: actionIcons.ExportPrivateKey, }); } diff --git a/components/types.ts b/components/types.ts index 95daf757a..d9f4b9835 100644 --- a/components/types.ts +++ b/components/types.ts @@ -16,6 +16,7 @@ export interface ToolTipMenuProps { actions: Action[] | Action[][]; children: React.ReactNode; enableAndroidRipple?: boolean; + dismissMenu?: () => void; onPressMenuItem: (id: string) => void; title?: string; isMenuPrimaryAction?: boolean; diff --git a/navigation/DetailViewScreensStack.tsx b/navigation/DetailViewScreensStack.tsx index 34156f1c9..9534ca315 100644 --- a/navigation/DetailViewScreensStack.tsx +++ b/navigation/DetailViewScreensStack.tsx @@ -359,19 +359,6 @@ const DetailViewStackScreensStack = () => { presentation: 'fullScreenModal', statusBarHidden: true, }} - initialParams={{ - isLoading: false, - cameraStatusGranted: undefined, - backdoorPressed: undefined, - launchedBy: undefined, - urTotal: undefined, - urHave: undefined, - backdoorText: '', - onDismiss: undefined, - showFileImportButton: true, - backdoorVisible: false, - animatedQRCodeData: {}, - }} /> diff --git a/navigation/DetailViewStackParamList.ts b/navigation/DetailViewStackParamList.ts index 86688233a..b5734244e 100644 --- a/navigation/DetailViewStackParamList.ts +++ b/navigation/DetailViewStackParamList.ts @@ -1,3 +1,5 @@ +import { LightningTransaction } from '../class/wallets/types'; + export type DetailViewStackParamList = { WalletsList: undefined; WalletTransactions: { walletID: string; walletType: string }; @@ -11,21 +13,32 @@ export type DetailViewStackParamList = { RBFBumpFee: { transactionId: string }; RBFCancel: { transactionId: string }; SelectWallet: undefined; - LNDViewInvoice: { invoiceId: string }; + LNDViewInvoice: { invoice: LightningTransaction; walletID: string }; LNDViewAdditionalInvoiceInformation: { invoiceId: string }; LNDViewAdditionalInvoicePreImage: { invoiceId: string }; Broadcast: undefined; IsItMyAddress: undefined; GenerateWord: undefined; LnurlPay: undefined; - LnurlPaySuccess: undefined; + LnurlPaySuccess: { + paymentHash: string; + justPaid: boolean; + fromWalletID: string; + }; LnurlAuth: undefined; Success: undefined; WalletAddresses: { walletID: string }; AddWalletRoot: undefined; SendDetailsRoot: undefined; LNDCreateInvoiceRoot: undefined; - ScanLndInvoiceRoot: undefined; + ScanLndInvoiceRoot: { + screen: string; + params: { + paymentHash: string; + fromWalletID: string; + justPaid: boolean; + }; + }; AztecoRedeemRoot: undefined; WalletExportRoot: undefined; ExportMultisigCoordinationSetupRoot: undefined; @@ -40,7 +53,9 @@ export type DetailViewStackParamList = { ElectrumSettings: undefined; EncryptStorage: undefined; Language: undefined; - LightningSettings: undefined; + LightningSettings: { + url?: string; + }; NotificationSettings: undefined; SelfTest: undefined; ReleaseNotes: undefined; @@ -48,20 +63,35 @@ export type DetailViewStackParamList = { SettingsPrivacy: undefined; ViewEditMultisigCosignersRoot: { walletID: string; cosigners: string[] }; WalletXpubRoot: undefined; - SignVerifyRoot: undefined; - ReceiveDetailsRoot: undefined; + SignVerifyRoot: { + screen: 'SignVerify'; + params: { + walletID: string; + address: string; + }; + }; + ReceiveDetailsRoot: { + screen: 'ReceiveDetails'; + params: { + walletID: string; + address: string; + }; + }; ScanQRCodeRoot: { - isLoading?: boolean; - cameraStatusGranted?: boolean; - backdoorPressed?: boolean; - launchedBy?: string; - urTotal?: number; - urHave?: number; - backdoorText?: string; - onDismiss?: () => void; - showFileImportButton?: boolean; - backdoorVisible?: boolean; - animatedQRCodeData?: Record; + screen: string; + params: { + isLoading: false; + cameraStatusGranted?: boolean; + backdoorPressed?: boolean; + launchedBy?: string; + urTotal?: number; + urHave?: number; + backdoorText?: string; + onDismiss?: () => void; + showFileImportButton: true; + backdoorVisible?: boolean; + animatedQRCodeData?: Record; + }; }; PaymentCodeRoot: undefined; ReorderWallets: undefined; diff --git a/screen/settings/lightningSettings.tsx b/screen/settings/lightningSettings.tsx index d8e3d0aef..b8275d75e 100644 --- a/screen/settings/lightningSettings.tsx +++ b/screen/settings/lightningSettings.tsx @@ -1,6 +1,6 @@ -import AsyncStorage from '@react-native-async-storage/async-storage'; -import { RouteProp, useNavigation, useRoute } from '@react-navigation/native'; import React, { useCallback, useEffect, useState } from 'react'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { RouteProp, useRoute } from '@react-navigation/native'; import { Alert, I18nManager, Linking, ScrollView, StyleSheet, TextInput, View } from 'react-native'; import { Button as ButtonRNElements } from 'react-native-elements'; @@ -11,7 +11,7 @@ import { LightningCustodianWallet } from '../../class/wallets/lightning-custodia import presentAlert from '../../components/Alert'; import { Button } from '../../components/Button'; import { useTheme } from '../../components/themes'; -import { requestCameraAuthorization } from '../../helpers/scan-qr'; +import { scanQrHelper } from '../../helpers/scan-qr'; import loc from '../../loc'; const styles = StyleSheet.create({ @@ -52,7 +52,6 @@ const LightningSettings: React.FC = () => { const [URI, setURI] = useState(); const { colors } = useTheme(); const route = useRoute(); - const navigation = useNavigation(); const styleHook = StyleSheet.create({ uri: { borderColor: colors.formBorder, @@ -114,17 +113,11 @@ const LightningSettings: React.FC = () => { }, [URI]); const importScan = () => { - requestCameraAuthorization().then(() => - // @ts-ignore: Address types later - navigation.navigate('ScanQRCodeRoot', { - screen: 'ScanQRCode', - params: { - launchedBy: route.name, - onBarScanned: setLndhubURI, - showFileImportButton: true, - }, - }), - ); + scanQrHelper(route.name).then(data => { + if (data) { + setLndhubURI(data); + } + }); }; return ( diff --git a/screen/transactions/details.tsx b/screen/transactions/details.tsx index 440a62ec4..4a6c675a6 100644 --- a/screen/transactions/details.tsx +++ b/screen/transactions/details.tsx @@ -1,5 +1,5 @@ import Clipboard from '@react-native-clipboard/clipboard'; -import { RouteProp, useFocusEffect, useNavigation, useRoute } from '@react-navigation/native'; +import { RouteProp, useFocusEffect, useRoute } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import assert from 'assert'; import dayjs from 'dayjs'; @@ -18,6 +18,8 @@ import navigationStyle from '../../components/navigationStyle'; import { useTheme } from '../../components/themes'; import ToolTipMenu from '../../components/TooltipMenu'; import loc from '../../loc'; +import { useExtendedNavigation } from '../../hooks/useExtendedNavigation'; +import { DetailViewStackParamList } from '../../navigation/DetailViewStackParamList'; interface TransactionDetailsProps { route: RouteProp<{ params: { hash: string; walletID: string } }, 'params'>; @@ -62,8 +64,10 @@ const toolTipMenuActions = [ }, ]; +type NavigationProps = NativeStackNavigationProp; + const TransactionDetails = () => { - const { setOptions, navigate } = useNavigation(); + const { setOptions, navigate } = useExtendedNavigation(); const { hash, walletID } = useRoute().params; const { saveToDisk, txMetadata, counterpartyMetadata, wallets, getTransactions } = useContext(BlueStorageContext); const [from, setFrom] = useState([]); @@ -204,7 +208,6 @@ const TransactionDetails = () => { }; const navigateToWallet = (wallet: TWallet) => { - // @ts-ignore idk how to fix it navigate('WalletTransactions', { walletID: wallet.getID(), walletType: wallet.type, diff --git a/screen/wallets/ViewEditMultisigCosigners.tsx b/screen/wallets/ViewEditMultisigCosigners.tsx index 3614dc60d..8bedb8b3a 100644 --- a/screen/wallets/ViewEditMultisigCosigners.tsx +++ b/screen/wallets/ViewEditMultisigCosigners.tsx @@ -18,7 +18,7 @@ import { } from 'react-native'; import { Badge, Icon } from 'react-native-elements'; -import { isDesktop } from '../../blue_modules/environment'; +import { isDesktop, isTablet } from '../../blue_modules/environment'; import { useStorage } from '../../blue_modules/storage-context'; import { encodeUR } from '../../blue_modules/ur'; import { @@ -191,7 +191,6 @@ const ViewEditMultisigCosigners: React.FC = () => { await wallet?.fetchBalance(); } newWallets.push(wallet); - // @ts-ignore wtf navigate('WalletsList'); setTimeout(() => { setWalletsWithNewOrder(newWallets); @@ -529,11 +528,9 @@ const ViewEditMultisigCosigners: React.FC = () => { }; const renderProvideMnemonicsModal = () => { - // @ts-ignore weird, property exists on type definition. might be some ts bugs - const isPad: boolean = Platform.isPad; return ( - + {loc.multisig.type_your_mnemonics} @@ -561,12 +558,9 @@ const ViewEditMultisigCosigners: React.FC = () => { }; const renderShareModal = () => { - // @ts-ignore weird, property exists on typedefinition. might be some ts bugs - const isPad: boolean = Platform.isPad; - return ( - + {loc.multisig.this_is_cosigners_xpub} {Platform.OS === 'ios' ? loc.multisig.this_is_cosigners_xpub_airdrop : ''} @@ -627,13 +621,11 @@ const ViewEditMultisigCosigners: React.FC = () => { }; const footer =