diff --git a/src/components/ScanIcon.ts b/src/components/ScanIcon.ts
new file mode 100644
index 00000000..e88c440a
--- /dev/null
+++ b/src/components/ScanIcon.ts
@@ -0,0 +1 @@
+export const ScanIcon = ''
\ No newline at end of file
diff --git a/src/components/index.ts b/src/components/index.ts
index be791acc..11dd5771 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -13,3 +13,4 @@ export * from "./ErrorModal"
export * from "./InfoModal"
export * from "./BottomModal"
export * from "./Loading"
+export * from "./ScanIcon"
diff --git a/src/i18n/en.ts b/src/i18n/en.ts
index b936cd7c..baba06a8 100644
--- a/src/i18n/en.ts
+++ b/src/i18n/en.ts
@@ -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)",
diff --git a/src/screens/ProfileScreen.tsx b/src/screens/ProfileScreen.tsx
index eda0a6fc..bb81a8b1 100644
--- a/src/screens/ProfileScreen.tsx
+++ b/src/screens/ProfileScreen.tsx
@@ -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 = 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 = observer(
const iconNpub = useThemeColor('textDim')
return (
-
+
+
{!walletProfileStore.isOwnProfile && (
diff --git a/src/screens/ReceiveOptionsScreen.tsx b/src/screens/ReceiveOptionsScreen.tsx
index e0547eba..e09531b2 100644
--- a/src/screens/ReceiveOptionsScreen.tsx
+++ b/src/screens/ReceiveOptionsScreen.tsx
@@ -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>
}
- 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>
tx="receiveScreen.showOrShareInvoice"
subTx="receiveScreen.showOrShareInvoiceDescription"
leftIcon='faBolt'
- leftIconColor={colors.palette.accent300}
+ leftIconColor={colors.palette.orange200}
leftIconInverse={true}
style={$item}
onPress={gotoTopup}
/>
-
+
+
+ }
+ // leftIcon='faQrcode'
+ // leftIconColor={colors.palette.success200}
+ // leftIconInverse={true}
style={$item}
topSeparator={true}
- onPress={onScanToken}
+ onPress={onScan}
/>
>
}
- FooterComponent={
-
- }
/>
{info && }
diff --git a/src/screens/ScanScreen.tsx b/src/screens/ScanScreen.tsx
index 85b64bb1..318c340b 100644
--- a/src/screens/ScanScreen.tsx
+++ b/src/screens/ScanScreen.tsx
@@ -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> = 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> = 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> = 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> = function ScanScree
return (shouldLoad ? (
<>
(isScanned ? undefined : onReadCode(event))}
hideControls
/>
+
+
+
+
{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,
+ }
+
diff --git a/src/screens/SendOptionsScreen.tsx b/src/screens/SendOptionsScreen.tsx
index a9db8b9b..ba122273 100644
--- a/src/screens/SendOptionsScreen.tsx
+++ b/src/screens/SendOptionsScreen.tsx
@@ -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> = 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> = obse
style={$item}
bottomSeparator={true}
onPress={gotoContacts}
- />
-
-
+ />
+
+
+
+ }
+ // leftIcon='faBolt'
+ // leftIconColor={colors.palette.success200}
+ // leftIconInverse={true}
+ topSeparator={true}
+ style={$item}
+ onPress={onScan}
+ />
>
}
diff --git a/src/screens/WalletScreen.tsx b/src/screens/WalletScreen.tsx
index a56320ca..188fdc5f 100644
--- a/src/screens/WalletScreen.tsx
+++ b/src/screens/WalletScreen.tsx
@@ -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 = observer(
/>