mirror of
https://github.com/minibits-cash/minibits_wallet.git
synced 2026-10-06 03:38:24 +00:00
Simplified payment navigation, fix profile sharing
This commit is contained in:
@@ -0,0 +1 @@
|
||||
export const ScanIcon = '<?xml version="1.0" encoding="utf-8"?><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve"><g id="XMLID_1_"> <path id="XMLID_7_" d="M59.3,93.2c0-8.6,6-14.6,14.6-14.6h83.3V19.3H75.6C34.4,19.3,0,52,0,93.2v83.3h59.3V93.2z M437.3,19.3h-83.3 v59.3h82.5c8.6,0,15.5,6,15.5,14.6v83.3h59.3V93.2C512,52,478.5,19.3,437.3,19.3z M452.7,416.2c0,8.6-6,14.6-14.6,14.6h-83.3V491 h83.3c41.2,0,73.9-34.4,73.9-75.6v-82.5h-59.3V416.2z M73.9,431.7c-8.6,0-14.6-6-14.6-14.6v-82.5H0v82.5c0,41.2,34.4,75.6,75.6,75.6h82.5v-60.1H73.9V431.7z"/></g></svg>'
|
||||
@@ -13,3 +13,4 @@ export * from "./ErrorModal"
|
||||
export * from "./InfoModal"
|
||||
export * from "./BottomModal"
|
||||
export * from "./Loading"
|
||||
export * from "./ScanIcon"
|
||||
|
||||
+8
-8
@@ -62,12 +62,12 @@ const en = {
|
||||
received: "Amount received:",
|
||||
sharePaymentRequest: "Send payment request",
|
||||
sharePaymentRequestDescription: "Send payment request to one of your contacts, so that the payer can pay you exact amount.",
|
||||
scanToReceive: "Scan ecash token",
|
||||
scanToReceiveDescription: "Scan ecash token to receive it into your wallet.",
|
||||
scanToReceive: "Scan or paste to receive",
|
||||
scanToReceiveDescription: "Scan or paste ecash token or lnurl withdraw link to receive into your wallet.",
|
||||
pasteToReceive: "Paste",
|
||||
pasteoReceiveDescription: "Paste ecash token to receive it into your wallet.",
|
||||
showOrShareInvoice: "Create lightning invoice",
|
||||
showOrShareInvoiceDescription: "Present or share the lightning invoice for an amount you want to receive." ,
|
||||
showOrShareInvoice: "Share lightning invoice",
|
||||
showOrShareInvoiceDescription: "Present or share lightning invoice for an amount you want to receive." ,
|
||||
scanWithdrawalLink: "Scan withdrawal link"
|
||||
},
|
||||
transferScreen: {
|
||||
@@ -80,12 +80,12 @@ const en = {
|
||||
title: "Send",
|
||||
sendToContact: "Send to contact",
|
||||
sendToContactDescription: "Send your ecash to one of your contacts stored in your contact list.",
|
||||
scanToSend: "Scan lightning invoice",
|
||||
scanToSendDescription: "Scan invoice, LNURL pay code or lightning address to pay to from your wallet.",
|
||||
scanToSend: "Scan or paste to send",
|
||||
scanToSendDescription: "Scan or paste invoice, lnurl pay code or lightning address to pay from your wallet.",
|
||||
pasteToSend: "Paste",
|
||||
pasteToSendDescription: "Paste lightning invoice from clipboard to pay it from your wallet.",
|
||||
showOrShareToken: "Share ecash token",
|
||||
showOrShareTokenDescription: "Present or share ecash for an amount you want to send.",
|
||||
showOrShareToken: "Share ecash",
|
||||
showOrShareTokenDescription: "Present or share ecash token for an amount you want to send.",
|
||||
},
|
||||
tranDetailScreen: {
|
||||
amount: "Amount (in satoshis)",
|
||||
|
||||
@@ -3,7 +3,7 @@ import React, {FC, useCallback, useEffect, useState} from 'react'
|
||||
import {ColorValue, Share, TextStyle, View, ViewStyle} from 'react-native'
|
||||
import {colors, spacing, useThemeColor} from '../theme'
|
||||
import {ContactsStackScreenProps} from '../navigation'
|
||||
import {Icon, ListItem, Screen, Text, Card, BottomModal, Button, InfoModal, ErrorModal, Loading} from '../components'
|
||||
import {Icon, ListItem, Screen, Text, Card, BottomModal, Button, InfoModal, ErrorModal, Loading, Header} from '../components'
|
||||
import {useHeader} from '../utils/useHeader'
|
||||
import {useStores} from '../models'
|
||||
import AppError from '../utils/AppError'
|
||||
@@ -19,13 +19,6 @@ interface ProfileScreenProps extends ContactsStackScreenProps<'Profile'> {}
|
||||
export const ProfileScreen: FC<ProfileScreenProps> = observer(
|
||||
function ProfileScreen({navigation}) {
|
||||
|
||||
useHeader({
|
||||
leftIcon: 'faArrowLeft',
|
||||
onLeftPress: () => navigation.goBack(),
|
||||
rightIcon: 'faShareFromSquare',
|
||||
onRightPress: () => onShareContact()
|
||||
})
|
||||
|
||||
const {walletProfileStore, userSettingsStore} = useStores()
|
||||
const {npub, name, picture, nip05} = walletProfileStore
|
||||
|
||||
@@ -116,7 +109,13 @@ export const ProfileScreen: FC<ProfileScreenProps> = observer(
|
||||
const iconNpub = useThemeColor('textDim')
|
||||
|
||||
return (
|
||||
<Screen contentContainerStyle={$screen} preset='auto'>
|
||||
<Screen contentContainerStyle={$screen} preset='auto'>
|
||||
<Header
|
||||
leftIcon='faArrowLeft'
|
||||
onLeftPress={navigation.goBack}
|
||||
rightIcon='faShareFromSquare'
|
||||
onRightPress={onShareContact}
|
||||
/>
|
||||
<ProfileHeader />
|
||||
<View style={$contentContainer}>
|
||||
{!walletProfileStore.isOwnProfile && (
|
||||
|
||||
@@ -3,18 +3,17 @@ import React, {FC, useState, useCallback} from 'react'
|
||||
import {useFocusEffect} from '@react-navigation/native'
|
||||
import {Alert, TextStyle, View, ViewStyle} from 'react-native'
|
||||
import Clipboard from '@react-native-clipboard/clipboard'
|
||||
import { SvgXml } from 'react-native-svg'
|
||||
import {spacing, useThemeColor, colors} from '../theme'
|
||||
import {WalletStackScreenProps} from '../navigation'
|
||||
import {
|
||||
Button,
|
||||
Icon,
|
||||
Card,
|
||||
Screen,
|
||||
InfoModal,
|
||||
ErrorModal,
|
||||
ListItem,
|
||||
BottomModal,
|
||||
Text,
|
||||
ScanIcon,
|
||||
} from '../components'
|
||||
import {useHeader} from '../utils/useHeader'
|
||||
import {log} from '../utils/logger'
|
||||
@@ -57,31 +56,8 @@ export const ReceiveOptionsScreen: FC<WalletStackScreenProps<'ReceiveOptions'>>
|
||||
}
|
||||
|
||||
|
||||
const onScanToken = async function () {
|
||||
navigation.navigate('Scan', {expectedType: IncomingDataType.CASHU})
|
||||
}
|
||||
|
||||
const onScanLnurl = async function () {
|
||||
navigation.navigate('Scan', {expectedType: IncomingDataType.LNURL})
|
||||
}
|
||||
|
||||
|
||||
const onPaste = async function () {
|
||||
const clipboard = await Clipboard.getString()
|
||||
if (!clipboard) {
|
||||
infoMessage('Please copy the ecash token first.')
|
||||
}
|
||||
|
||||
try {
|
||||
const incomingData = IncomingParser.findAndExtract(clipboard, IncomingDataType.CASHU)
|
||||
|
||||
infoMessage('Found ecash token in the clipboard.')
|
||||
setTimeout(() => navigation.navigate('Receive', {encodedToken: incomingData.encoded}), 1000)
|
||||
return
|
||||
|
||||
} catch (e: any) {
|
||||
handleError(e)
|
||||
}
|
||||
const onScan = async function () {
|
||||
navigation.navigate('Scan', {})
|
||||
}
|
||||
|
||||
|
||||
@@ -121,39 +97,41 @@ export const ReceiveOptionsScreen: FC<WalletStackScreenProps<'ReceiveOptions'>>
|
||||
tx="receiveScreen.showOrShareInvoice"
|
||||
subTx="receiveScreen.showOrShareInvoiceDescription"
|
||||
leftIcon='faBolt'
|
||||
leftIconColor={colors.palette.accent300}
|
||||
leftIconColor={colors.palette.orange200}
|
||||
leftIconInverse={true}
|
||||
style={$item}
|
||||
onPress={gotoTopup}
|
||||
/>
|
||||
<Button
|
||||
onPress={onScanLnurl}
|
||||
tx='receiveScreen.scanWithdrawalLink'
|
||||
preset='secondary'
|
||||
textStyle={{fontSize: 14, color: iconColor}}
|
||||
style={{alignSelf: 'flex-start', marginLeft: 43, minHeight: 25, paddingVertical: spacing.extraSmall, marginBottom: spacing.small}}
|
||||
/>
|
||||
<ListItem
|
||||
tx="receiveScreen.scanToReceive"
|
||||
subTx="receiveScreen.scanToReceiveDescription"
|
||||
leftIcon='faQrcode'
|
||||
leftIconColor={colors.palette.success200}
|
||||
leftIconInverse={true}
|
||||
LeftComponent={
|
||||
<View
|
||||
style={{
|
||||
marginEnd: spacing.small,
|
||||
flex: 0,
|
||||
borderRadius: spacing.small,
|
||||
padding: spacing.extraSmall,
|
||||
backgroundColor: colors.palette.success200
|
||||
}}
|
||||
>
|
||||
<SvgXml
|
||||
width={spacing.medium}
|
||||
height={spacing.medium}
|
||||
xml={ScanIcon}
|
||||
fill='white'
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
// leftIcon='faQrcode'
|
||||
// leftIconColor={colors.palette.success200}
|
||||
// leftIconInverse={true}
|
||||
style={$item}
|
||||
topSeparator={true}
|
||||
onPress={onScanToken}
|
||||
onPress={onScan}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
FooterComponent={
|
||||
<Button
|
||||
onPress={onPaste}
|
||||
tx='receiveScreen.pasteToReceive'
|
||||
preset='secondary'
|
||||
textStyle={{fontSize: 14, color: iconColor}}
|
||||
style={{alignSelf: 'flex-start', marginLeft: 43, minHeight: 25, paddingVertical: spacing.extraSmall, marginBottom: spacing.small}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
{info && <InfoModal message={info} />}
|
||||
|
||||
+77
-29
@@ -3,17 +3,20 @@ import {
|
||||
Platform,
|
||||
PermissionsAndroid,
|
||||
Alert,
|
||||
ViewStyle,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import {WalletStackScreenProps} from '../navigation'
|
||||
import {CameraScreen} from 'react-native-camera-kit'
|
||||
import {typography} from '../theme'
|
||||
import {CameraScreen, CameraType} from 'react-native-camera-kit'
|
||||
import {spacing, typography} from '../theme'
|
||||
import {useHeader} from '../utils/useHeader'
|
||||
import {log} from '../utils/logger'
|
||||
import { IncomingDataType, IncomingParser } from '../services/incomingParser'
|
||||
import AppError from '../utils/AppError'
|
||||
import { ErrorModal } from '../components'
|
||||
import { Button, ErrorModal } from '../components'
|
||||
import { LnurlUtils } from '../services/lnurl/lnurlUtils'
|
||||
import { infoMessage } from '../utils/utils'
|
||||
import Clipboard from '@react-native-clipboard/clipboard'
|
||||
|
||||
const hasAndroidCameraPermission = async () => {
|
||||
const cameraPermission = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA)
|
||||
@@ -56,48 +59,57 @@ export const ScanScreen: FC<WalletStackScreenProps<'Scan'>> = function ScanScree
|
||||
}, [route.params?.expectedType])
|
||||
|
||||
|
||||
|
||||
const onReadCode = async function(event: any) {
|
||||
setIsScanned(true)
|
||||
const scanned = event.nativeEvent.codeStringValue
|
||||
log.trace('Scanned', scanned)
|
||||
|
||||
return onIncomingData(scanned)
|
||||
}
|
||||
|
||||
|
||||
const onIncomingData = async function(incoming: any) {
|
||||
const routes = navigation.getState()?.routes
|
||||
const prevRouteName = routes[routes.length - 2].name
|
||||
log.trace('prevRouteName', prevRouteName)
|
||||
|
||||
|
||||
switch (prevRouteName) {
|
||||
case 'ReceiveOptions':
|
||||
log.trace('ReceiveOptions')
|
||||
try {
|
||||
if(expected === IncomingDataType.CASHU) {
|
||||
const tokenResult = IncomingParser.findAndExtract(scanned, IncomingDataType.CASHU)
|
||||
log.trace('Got token')
|
||||
return IncomingParser.navigateWithIncomingData(tokenResult, navigation)
|
||||
}
|
||||
try {
|
||||
const tokenResult = IncomingParser.findAndExtract(incoming, IncomingDataType.CASHU)
|
||||
return IncomingParser.navigateWithIncomingData(tokenResult, navigation)
|
||||
|
||||
if(expected === IncomingDataType.LNURL) {
|
||||
const lnurlResult = IncomingParser.findAndExtract(scanned, IncomingDataType.LNURL)
|
||||
log.trace('Got LNURL')
|
||||
await IncomingParser.navigateWithIncomingData(lnurlResult, navigation)
|
||||
return
|
||||
}
|
||||
} catch (e: any) {
|
||||
e.params = scanned
|
||||
const maybeLnurl = LnurlUtils.findEncodedLnurl(incoming)
|
||||
|
||||
if(maybeLnurl) {
|
||||
log.trace('Found LNURL link instead of a token', maybeLnurl, 'onIncomingData')
|
||||
const encodedLnurl = LnurlUtils.extractEncodedLnurl(maybeLnurl)
|
||||
|
||||
if(encodedLnurl) {
|
||||
infoMessage('Found LNURL link in the clipboard.')
|
||||
return setTimeout(async() => IncomingParser.navigateWithIncomingData({
|
||||
type: IncomingDataType.LNURL,
|
||||
encoded: encodedLnurl
|
||||
}, navigation), 500)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
e.params = incoming
|
||||
handleError(e)
|
||||
}
|
||||
case 'SendOptions':
|
||||
try {
|
||||
const invoiceResult = IncomingParser.findAndExtract(scanned, IncomingDataType.INVOICE)
|
||||
log.trace('Got invoice')
|
||||
const invoiceResult = IncomingParser.findAndExtract(incoming, IncomingDataType.INVOICE)
|
||||
return IncomingParser.navigateWithIncomingData(invoiceResult, navigation)
|
||||
|
||||
} catch (e: any) {
|
||||
const maybeLnurl = LnurlUtils.findEncodedLnurl(scanned)
|
||||
const maybeLnurl = LnurlUtils.findEncodedLnurl(incoming)
|
||||
|
||||
if(maybeLnurl) {
|
||||
log.trace('Found LNURL link instead of an invoice', maybeLnurl, 'onPaste')
|
||||
log.trace('Found LNURL link instead of an invoice', maybeLnurl, 'onIncomingData')
|
||||
const encodedLnurl = LnurlUtils.extractEncodedLnurl(maybeLnurl)
|
||||
|
||||
if(encodedLnurl) {
|
||||
@@ -110,10 +122,10 @@ export const ScanScreen: FC<WalletStackScreenProps<'Scan'>> = function ScanScree
|
||||
return
|
||||
}
|
||||
|
||||
const maybeLnurlAddress = LnurlUtils.findEncodedLnurlAddress(scanned)
|
||||
const maybeLnurlAddress = LnurlUtils.findEncodedLnurlAddress(incoming)
|
||||
|
||||
if(maybeLnurlAddress) {
|
||||
log.trace('Found Lightning address instead of an invoice', maybeLnurlAddress, 'onPaste')
|
||||
log.trace('Found Lightning address instead of an invoice', maybeLnurlAddress, 'onIncomingData')
|
||||
const lnurlAddress = LnurlUtils.extractLnurlAddress(maybeLnurlAddress)
|
||||
|
||||
if(lnurlAddress) {
|
||||
@@ -126,22 +138,31 @@ export const ScanScreen: FC<WalletStackScreenProps<'Scan'>> = function ScanScree
|
||||
return
|
||||
}
|
||||
|
||||
e.params = scanned
|
||||
e.params = incoming
|
||||
handleError(e)
|
||||
break
|
||||
}
|
||||
default:
|
||||
try {
|
||||
// generic scan button on wallet screen
|
||||
const incomingData = IncomingParser.findAndExtract(scanned)
|
||||
const incomingData = IncomingParser.findAndExtract(incoming)
|
||||
return IncomingParser.navigateWithIncomingData(incomingData, navigation)
|
||||
} catch (e: any) {
|
||||
e.params = scanned
|
||||
e.params = incoming
|
||||
handleError(e)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const onPaste = async function() {
|
||||
const clipboard = await Clipboard.getString()
|
||||
if (!clipboard) {
|
||||
infoMessage('Please copy the invoice first.')
|
||||
}
|
||||
|
||||
return onIncomingData(clipboard)
|
||||
}
|
||||
|
||||
|
||||
/* const handleError = (scanned: string, message: string) => {
|
||||
@@ -161,14 +182,41 @@ export const ScanScreen: FC<WalletStackScreenProps<'Scan'>> = function ScanScree
|
||||
return (shouldLoad ? (
|
||||
<>
|
||||
<CameraScreen
|
||||
actions={{rightButtonText: 'Done', leftButtonText: 'Cancel'}}
|
||||
cameraType={CameraType.Back}
|
||||
scanBarcode
|
||||
onReadCode={event => (isScanned ? undefined : onReadCode(event))}
|
||||
hideControls
|
||||
/>
|
||||
<View style={$bottomContainer}>
|
||||
<View style={$buttonContainer}>
|
||||
<Button
|
||||
onPress={() => onPaste()}
|
||||
text={'Paste from clipboard'}
|
||||
preset='secondary'
|
||||
style={{marginTop: spacing.medium, minWidth: 120}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
{error && <ErrorModal error={error} />}
|
||||
</>
|
||||
) : null
|
||||
)
|
||||
}
|
||||
|
||||
const $buttonContainer: ViewStyle = {
|
||||
flexDirection: 'row',
|
||||
alignSelf: 'center',
|
||||
}
|
||||
|
||||
const $bottomContainer: ViewStyle = {
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
flex: 1,
|
||||
justifyContent: 'flex-end',
|
||||
marginBottom: spacing.medium,
|
||||
alignSelf: 'stretch',
|
||||
// opacity: 0,
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
ListItem,
|
||||
BottomModal,
|
||||
Text,
|
||||
ScanIcon,
|
||||
} from '../components'
|
||||
import {useHeader} from '../utils/useHeader'
|
||||
import {log} from '../utils/logger'
|
||||
@@ -23,6 +24,7 @@ import useIsInternetReachable from '../utils/useIsInternetReachable'
|
||||
import { infoMessage } from '../utils/utils'
|
||||
import { IncomingDataType, IncomingParser } from '../services/incomingParser'
|
||||
import { LnurlUtils } from '../services/lnurl/lnurlUtils'
|
||||
import { SvgXml } from 'react-native-svg'
|
||||
|
||||
export enum SendOption {
|
||||
SEND_TOKEN = 'SEND_TOKEN',
|
||||
@@ -63,58 +65,6 @@ export const SendOptionsScreen: FC<WalletStackScreenProps<'SendOptions'>> = obse
|
||||
}
|
||||
|
||||
|
||||
const onPaste = async function () {
|
||||
const clipboard = await Clipboard.getString()
|
||||
if (!clipboard) {
|
||||
infoMessage('Please copy the invoice first.')
|
||||
}
|
||||
|
||||
try {
|
||||
const incomingData = IncomingParser.findAndExtract(clipboard, IncomingDataType.INVOICE)
|
||||
|
||||
infoMessage('Found lightning invoice in the clipboard.')
|
||||
setTimeout(async() => IncomingParser.navigateWithIncomingData(incomingData, navigation), 500)
|
||||
return
|
||||
|
||||
} catch (e: any) {
|
||||
const maybeLnurl = LnurlUtils.findEncodedLnurl(clipboard)
|
||||
|
||||
if(maybeLnurl) {
|
||||
log.trace('Found LNURL link instead of an invoice', maybeLnurl, 'onPaste')
|
||||
const encodedLnurl = LnurlUtils.extractEncodedLnurl(maybeLnurl)
|
||||
|
||||
if(encodedLnurl) {
|
||||
infoMessage('Found LNURL link in the clipboard.')
|
||||
return setTimeout(async() => IncomingParser.navigateWithIncomingData({
|
||||
type: IncomingDataType.LNURL,
|
||||
encoded: encodedLnurl
|
||||
}, navigation), 500)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const maybeLnurlAddress = LnurlUtils.findEncodedLnurlAddress(clipboard)
|
||||
|
||||
if(maybeLnurlAddress) {
|
||||
log.trace('Found Lightning address instead of an invoice', maybeLnurlAddress, 'onPaste')
|
||||
const lnurlAddress = LnurlUtils.extractLnurlAddress(maybeLnurlAddress)
|
||||
|
||||
if(lnurlAddress) {
|
||||
infoMessage('Found Lightning address in the clipboard.')
|
||||
return setTimeout(async() => IncomingParser.navigateWithIncomingData({
|
||||
type: IncomingDataType.LNURL_ADDRESS,
|
||||
encoded: lnurlAddress
|
||||
}, navigation), 500)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
e.params = clipboard
|
||||
handleError(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const handleError = function (e: AppError): void {
|
||||
log.error(e.name, e.message)
|
||||
setError(e)
|
||||
@@ -146,33 +96,44 @@ export const SendOptionsScreen: FC<WalletStackScreenProps<'SendOptions'>> = obse
|
||||
style={$item}
|
||||
bottomSeparator={true}
|
||||
onPress={gotoContacts}
|
||||
/>
|
||||
<ListItem
|
||||
tx="sendScreen.scanToSend"
|
||||
subTx="sendScreen.scanToSendDescription"
|
||||
leftIcon='faBolt'
|
||||
leftIconColor={colors.palette.accent300}
|
||||
leftIconInverse={true}
|
||||
style={$item}
|
||||
onPress={onScan}
|
||||
/>
|
||||
<Button
|
||||
onPress={onPaste}
|
||||
tx='sendScreen.pasteToSend'
|
||||
preset='secondary'
|
||||
textStyle={{fontSize: 14, color: iconColor}}
|
||||
style={{alignSelf: 'flex-start', marginLeft: 43, minHeight: 25, paddingVertical: spacing.extraSmall, marginBottom: spacing.small}}
|
||||
/>
|
||||
/>
|
||||
<ListItem
|
||||
tx="sendScreen.showOrShareToken"
|
||||
subTx="sendScreen.showOrShareTokenDescription"
|
||||
leftIcon='faQrcode'
|
||||
leftIconColor={colors.palette.success200}
|
||||
leftIconColor={colors.palette.iconViolet300}
|
||||
leftIconInverse={true}
|
||||
style={$item}
|
||||
topSeparator={true}
|
||||
onPress={gotoSend}
|
||||
/>
|
||||
<ListItem
|
||||
tx="sendScreen.scanToSend"
|
||||
subTx="sendScreen.scanToSendDescription"
|
||||
LeftComponent={
|
||||
<View
|
||||
style={{
|
||||
marginEnd: spacing.small,
|
||||
flex: 0,
|
||||
borderRadius: spacing.small,
|
||||
padding: spacing.extraSmall,
|
||||
backgroundColor: colors.palette.success200
|
||||
}}
|
||||
>
|
||||
<SvgXml
|
||||
width={spacing.medium}
|
||||
height={spacing.medium}
|
||||
xml={ScanIcon}
|
||||
fill='white'
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
// leftIcon='faBolt'
|
||||
// leftIconColor={colors.palette.success200}
|
||||
// leftIconInverse={true}
|
||||
topSeparator={true}
|
||||
style={$item}
|
||||
onPress={onScan}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {observer} from 'mobx-react-lite'
|
||||
import React, {FC, useState, useEffect, useCallback, useRef, useMemo, createRef, RefObject} from 'react'
|
||||
import React, {FC, useState, useEffect, useCallback, useRef} from 'react'
|
||||
import {useFocusEffect} from '@react-navigation/native'
|
||||
import {
|
||||
TextStyle,
|
||||
@@ -10,18 +10,15 @@ import {
|
||||
Image,
|
||||
InteractionManager,
|
||||
Animated,
|
||||
findNodeHandle,
|
||||
FlatList,
|
||||
Pressable,
|
||||
Linking
|
||||
} from 'react-native'
|
||||
/* import Animated, {
|
||||
useAnimatedScrollHandler,
|
||||
useSharedValue,
|
||||
useAnimatedStyle,
|
||||
} from 'react-native-reanimated' */
|
||||
import codePush, { RemotePackage } from 'react-native-code-push'
|
||||
import {verticalScale} from '@gocodingnow/rn-size-matters'
|
||||
import { SvgXml } from 'react-native-svg'
|
||||
import PagerView, { PagerViewOnPageScrollEventData } from 'react-native-pager-view'
|
||||
import { ScalingDot } from 'react-native-animated-pagination-dots'
|
||||
import {useThemeColor, spacing, colors, typography} from '../theme'
|
||||
import {
|
||||
Button,
|
||||
@@ -35,12 +32,11 @@ import {
|
||||
BottomModal,
|
||||
ErrorModal,
|
||||
Header,
|
||||
ScanIcon
|
||||
} from '../components'
|
||||
import {useStores} from '../models'
|
||||
import EventEmitter from '../utils/eventEmitter'
|
||||
import {WalletStackScreenProps} from '../navigation'
|
||||
// import useIsInternetReachable from '../utils/useIsInternetReachable'
|
||||
import {useHeader} from '../utils/useHeader'
|
||||
import {Mint, MintBalance} from '../models/Mint'
|
||||
import {MintsByHostname} from '../models/MintsStore'
|
||||
import {Env, log} from '../utils/logger'
|
||||
@@ -49,7 +45,6 @@ import {TransactionListItem} from './Transactions/TransactionListItem'
|
||||
import {MintClient, MintKeys, NostrClient, ReceivedEventResult, Wallet} from '../services'
|
||||
import {translate} from '../i18n'
|
||||
import AppError, { Err } from '../utils/AppError'
|
||||
import { ResultModalInfo } from './Wallet/ResultModalInfo'
|
||||
import {
|
||||
APP_ENV,
|
||||
CODEPUSH_STAGING_DEPLOYMENT_KEY,
|
||||
@@ -57,14 +52,14 @@ import {
|
||||
} from '@env'
|
||||
import { round } from '../utils/number'
|
||||
import { NotificationService } from '../services/notificationService'
|
||||
import PagerView, { PagerViewOnPageScrollEventData } from 'react-native-pager-view'
|
||||
import { ExpandingDot, ScalingDot, SlidingBorder, SlidingDot } from 'react-native-animated-pagination-dots'
|
||||
import { PaymentRequest, PaymentRequestStatus } from '../models/PaymentRequest'
|
||||
import { Invoice } from '../models/Invoice'
|
||||
import { poller } from '../utils/poller'
|
||||
import Clipboard from '@react-native-clipboard/clipboard'
|
||||
import { IncomingDataType, IncomingParser } from '../services/incomingParser'
|
||||
|
||||
|
||||
|
||||
const AnimatedPagerView = Animated.createAnimatedComponent(PagerView)
|
||||
const deploymentKey = APP_ENV === Env.PROD ? CODEPUSH_PRODUCTION_DEPLOYMENT_KEY : CODEPUSH_STAGING_DEPLOYMENT_KEY
|
||||
|
||||
@@ -498,10 +493,11 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
|
||||
/>
|
||||
<Button
|
||||
RightAccessory={() => (
|
||||
<Icon
|
||||
icon='faExpand'
|
||||
color='white'
|
||||
size={spacing.medium}
|
||||
<SvgXml
|
||||
width={spacing.medium}
|
||||
height={spacing.medium}
|
||||
xml={ScanIcon}
|
||||
fill='white'
|
||||
/>
|
||||
)}
|
||||
onPress={gotoScan}
|
||||
@@ -657,31 +653,7 @@ const MintsByHostnameListItem = observer(function (props: {
|
||||
)
|
||||
})
|
||||
|
||||
/* const LightningActionsBlock = function (props: {
|
||||
gotoWithdraw: any
|
||||
gotoTopup: any
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<ListItem
|
||||
tx='walletScreen.topUpWallet'
|
||||
subTx='walletScreen.topUpWalletSubText'
|
||||
leftIcon='faArrowRightToBracket'
|
||||
leftIconTransform='rotate-90'
|
||||
onPress={props.gotoTopup}
|
||||
bottomSeparator={true}
|
||||
style={{paddingHorizontal: spacing.medium}}
|
||||
/>
|
||||
<ListItem
|
||||
tx='walletScreen.transferFromWallet'
|
||||
subTx='walletScreen.transferFromWalletSubText'
|
||||
leftIcon='faArrowUpFromBracket'
|
||||
onPress={props.gotoWithdraw}
|
||||
style={{paddingHorizontal: spacing.medium}}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
} */
|
||||
|
||||
|
||||
const $screen: ViewStyle = {
|
||||
flex: 1,
|
||||
|
||||
@@ -43,12 +43,19 @@ const extractEncodedLightningInvoice = function (maybeInvoice: string) {
|
||||
}
|
||||
|
||||
invoice = decodeInvoice(encodedInvoice) // throws
|
||||
return encodedInvoice
|
||||
|
||||
} else {
|
||||
invoice = decodeInvoice(maybeInvoice) // throws
|
||||
return maybeInvoice
|
||||
return encodedInvoice
|
||||
}
|
||||
|
||||
if (maybeInvoice.startsWith('bitcoin:')) {
|
||||
const url = new URL(maybeInvoice)
|
||||
// Use URLSearchParams to get the value of the "lightning" parameter
|
||||
encodedInvoice = url.searchParams.get("lightning") as string
|
||||
invoice = decodeInvoice(encodedInvoice) // throws
|
||||
return encodedInvoice
|
||||
}
|
||||
|
||||
invoice = decodeInvoice(maybeInvoice) // throws
|
||||
return maybeInvoice
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ const palette = {
|
||||
blue200: '#818AFF',
|
||||
|
||||
orange200: '#FFAB51',
|
||||
orange400: '#F7931A',
|
||||
|
||||
focus100: '#FB4E9E',
|
||||
focus200: '#F62586',
|
||||
@@ -58,6 +59,7 @@ const palette = {
|
||||
iconGreyBlue400: '#0E629B',
|
||||
iconMagenta200: '#F62586',
|
||||
iconViolet200: '#AF00C9',
|
||||
iconViolet300: '#7F38CA',
|
||||
} as const
|
||||
|
||||
export const colors = {
|
||||
|
||||
Reference in New Issue
Block a user