Wallet screen redesign MVP

This commit is contained in:
minibits-cash
2024-09-24 22:02:00 +02:00
parent 51eb985fe4
commit b3e78262b1
8 changed files with 437 additions and 271 deletions
+26
View File
@@ -0,0 +1,26 @@
diff --git a/node_modules/react-native-tab-view/src/TabBar.tsx b/node_modules/react-native-tab-view/src/TabBar.tsx
index e8d0b4c..1c3c09f 100644
--- a/node_modules/react-native-tab-view/src/TabBar.tsx
+++ b/node_modules/react-native-tab-view/src/TabBar.tsx
@@ -364,8 +364,7 @@ export function TabBar<T extends Route>({
const renderItem = React.useCallback(
({ item: route, index }: ListRenderItemInfo<T>) => {
- const props: TabBarItemProps<T> & { key: string } = {
- key: route.key,
+ const props: TabBarItemProps<T> = {
position: position,
route: route,
navigationState: navigationState,
@@ -446,9 +445,9 @@ export function TabBar<T extends Route>({
<>
{gap > 0 && index > 0 ? <Separator width={gap} /> : null}
{renderTabBarItem ? (
- renderTabBarItem(props)
+ renderTabBarItem({ key: route.key, ...props })
) : (
- <TabBarItem {...props} />
+ <TabBarItem key={route.key} {...props} />
)}
</>
);
+3 -2
View File
@@ -74,8 +74,9 @@ const nwcPngUrl = 'https://1044827509-files.gitbook.io/~/files/v0/b/gitbook-x-pr
const getConnectionRelays = function () {
const minibitsRelays = NostrClient.getMinibitsRelays()
const publicRelays = NostrClient.getDefaultRelays()
return [...minibitsRelays, ...publicRelays]
// const publicRelays = NostrClient.getDefaultRelays()
// return [...minibitsRelays, ...publicRelays]
return minibitsRelays
}
const getSupportedMethods = function () {
+2 -3
View File
@@ -303,8 +303,7 @@ export const ReceiveScreen: FC<WalletStackScreenProps<'Receive'>> = observer(
{transactionStatus !== TransactionStatus.COMPLETED && (
<Card
style={$card}
heading={'Receive to'}
headingStyle={{textAlign: 'center', padding: spacing.small}}
label={'Receive to'}
ContentComponent={
<>
{CashuUtils.getMintsFromToken(token).map((mintUrl, index) => {
@@ -526,7 +525,7 @@ const $contentContainer: TextStyle = {
const $card: ViewStyle = {
// marginTop: - spacing.extraLarge * 2,
marginBottom: spacing.small,
paddingTop: 0,
// paddingTop: 0,
}
const $memoCard: ViewStyle = {
+11 -3
View File
@@ -1833,10 +1833,14 @@ export const TranItem = function (props: {
<View>
<Text
style={[props.labelStyle, {color: labelColor, fontSize: 14}, margin]}
tx={props.label}
tx={props.label}
/>
{props.isCurrency && props.unit ? (
<Text style={props.valueStyle ?? {}} text={`${formatCurrency(props.value as number, getCurrency(props.unit).code)} ${getCurrency(props.unit).code}`} />
<Text
style={props.valueStyle ?? {}}
text={`${formatCurrency(props.value as number, getCurrency(props.unit).code)} ${getCurrency(props.unit).code}`}
selectable={true}
/>
) : (
<>
{props.url ? (
@@ -1844,7 +1848,11 @@ export const TranItem = function (props: {
<Text style={props.valueStyle ?? {textDecorationLine: 'underline'}} text={props.value as string} />
</Pressable>
) : (
<Text style={props.valueStyle ?? {}} text={props.value as string} />
<Text
selectable={true}
style={props.valueStyle ?? {}}
text={props.value as string}
/>
)}
</>
)}
+1 -1
View File
@@ -47,7 +47,7 @@ export const CurrencyAmount = observer(function (props: {
<Text
style={[$symbol, {
color: symbolColor,
fontSize: size && spacing[size] * 0.5 || spacing.small * 0.5,
fontSize: size && spacing[size] * 0.6 || spacing.small * 0.6,
fontFamily: typography.primary?.light,
// lineHeight: size && spacing[size] * 1 || spacing.small * 1
+380 -255
View File
@@ -12,15 +12,12 @@ import {
FlatList,
Pressable,
Linking,
LayoutAnimation,
ScrollView
LayoutAnimation,
} from 'react-native'
import codePush, { RemotePackage } from 'react-native-code-push'
import {moderateScale, moderateVerticalScale, verticalScale} from '@gocodingnow/rn-size-matters'
import { SvgXml } from 'react-native-svg'
import {getUnixTime} from 'date-fns'
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,
@@ -59,24 +56,16 @@ import { round } from '../utils/number'
import { IncomingParser } from '../services/incomingParser'
import useIsInternetReachable from '../utils/useIsInternetReachable'
import { CurrencySign } from './Wallet/CurrencySign'
import { Currencies, MintUnit, getCurrency } from "../services/wallet/currency"
import { MintUnit, getCurrency } from "../services/wallet/currency"
import { CurrencyAmount } from './Wallet/CurrencyAmount'
import { LeftProfileHeader } from './ContactsScreen'
import { maxTransactionsByUnit } from '../models/TransactionsStore'
import { NotificationService } from '../services/notificationService'
import { TabBar, TabView } from 'react-native-tab-view'
import { NavigationState, Route, TabBar, TabView } from 'react-native-tab-view'
const AnimatedPagerView = Animated.createAnimatedComponent(PagerView)
const deploymentKey = APP_ENV === Env.PROD ? CODEPUSH_PRODUCTION_DEPLOYMENT_KEY : CODEPUSH_STAGING_DEPLOYMENT_KEY
interface WalletScreenProps extends WalletStackScreenProps<'Wallet'> {}
type RelayStatus = {
relay: string,
status: number,
error?: string
}
export const WalletScreen: FC<WalletScreenProps> = observer(
function WalletScreen({route, navigation}) {
const {
@@ -87,20 +76,29 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
userSettingsStore,
nwcStore,
walletProfileStore
} = useStores()
const pagerRef = useRef<PagerView>(null)
} = useStores()
const appState = useRef(AppState.currentState)
const isInternetReachable = useIsInternetReachable()
const groupedMints: MintsByUnit[] = mintsStore.groupedByUnit
// Tab view by unit
const [routes] = useState(
groupedMints.map((mintUnit) => ({
key: mintUnit.unit,
title: getCurrency(mintUnit.unit).code,
}))
)
const [tabIndex, setTabIndex] = useState(0)
const [currentUnit, setCurrentUnit] = useState<MintUnit>(groupedMints.length > 0 ? groupedMints[0].unit : 'sat')
const [info, setInfo] = useState<string>('')
const [defaultMintUrl, setDefaultMintUrl] = useState<string>(MINIBITS_MINT_URL)
const [lastClaimCheck, setLastClaimCheck] = useState<number>(getUnixTime(new Date()))
const [error, setError] = useState<AppError | undefined>()
const [isLoading, setIsLoading] = useState<boolean>(false)
const [isMintsModalVisible, setIsMintsModalVisible] = useState<boolean>(false)
const [isUpdateAvailable, setIsUpdateAvailable] = useState<boolean>(false)
const [isUpdateModalVisible, setIsUpdateModalVisible] = useState<boolean>(false)
const [isSendModalVisible, setIsSendModalVisible] = useState<boolean>(false)
@@ -164,10 +162,13 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
WalletTask.handleInFlight().catch(e => false)
// Create websocket subscriptions to receive tokens or payment requests by NOSTR DMs
WalletTask.receiveEventsFromRelays().catch(e => false)
// log.trace('[getInitialData]', 'walletProfile', walletProfileStore)
// Set wallet tab to preferred unit
const preferredUnit: MintUnit = userSettingsStore.preferredUnit
const pageIndex = groupedMints.findIndex((m) => m.unit === preferredUnit)
pagerRef.current && pagerRef.current.setPage(pageIndex)
const preferredTabIndex = routes.findIndex(route => route.key === preferredUnit)
if(tabIndex !== preferredTabIndex) {
onTabChange(preferredTabIndex)
}
// Create websocket subscriptions to receive NWC requests from remote wallets (if any)
// go through websockets only if remote notifications not working as push data messages are
@@ -183,6 +184,24 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
}, [])
const onTabChange = (tabIndex: number) => {
if(groupedMints.length === 0) {
return
}
const currentUnit = routes[tabIndex].key
log.trace('[onTabChange] currentUnit', currentUnit)
setCurrentUnit(currentUnit)
setTabIndex(tabIndex)
const preferredUnit = userSettingsStore.preferredUnit
if(currentUnit !== preferredUnit) { // prevents db write on first load
userSettingsStore.setPreferredUnit(currentUnit)
}
}
const handleDeeplink = async function ({url}: {url: string}) {
try {
@@ -286,6 +305,11 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
}, [])
const toggleMintsModal = () => {
setIsMintsModalVisible(previousState => !previousState)
}
const toggleUpdateModal = () => {
setIsUpdateModalVisible(previousState => !previousState)
}
@@ -325,16 +349,6 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
}
}
const gotoSend = function () {
toggleSendModal()
navigation.navigate('Send', {unit: currentUnit})
}
const gotoLightningPay = async function () {
toggleSendModal()
navigation.navigate('LightningPay', {unit: currentUnit})
}
const gotoScan = function () {
navigation.navigate('Scan')
}
@@ -344,11 +358,6 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
navigation.navigate('TokenReceive', {unit: currentUnit})
}
const gotoTopup = function () {
toggleReceiveModal()
navigation.navigate('Topup', {unit: currentUnit})
}
const gotoTranDetail = function (id: number) {
// navigation.navigate('TranDetail', {id})
navigation.navigate('TransactionsNavigator', {screen: 'TranDetail', params: {id}, initial: false})
@@ -362,56 +371,120 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
navigation.navigate('ContactsNavigator', {screen: 'Profile', params: {}, initial: false})
}
const gotoMintInfo = function (mintUrl: string) {
setIsMintsModalVisible(false)
navigation.navigate('SettingsNavigator', {
screen: 'MintInfo',
params: {mintUrl},
initial: false
})
}
const gotoTopup = function (mintUrl?: string) {
if(mintUrl) {
setIsMintsModalVisible(false)
navigation.navigate('Topup', {
mintUrl,
unit: currentUnit
})
} else {
setIsReceiveModalVisible(false)
navigation.navigate('Topup', {
unit: currentUnit
})
}
}
const gotoLightningPay = function (mintUrl?: string, ) {
if(mintUrl) {
setIsMintsModalVisible(false)
navigation.navigate('LightningPay', {
mintUrl,
unit: currentUnit
})
} else {
setIsSendModalVisible(false)
navigation.navigate('LightningPay', {
unit: currentUnit
})
}
}
const gotoSend = function () {
// log.trace('[gotoSend]', {currentUnit})
setIsSendModalVisible(false)
navigation.navigate('Send', {
unit: currentUnit
})
}
const handleError = function (e: AppError) {
setIsLoading(false)
setError(e)
}
// Tab view by unit
const [routes] = useState(
groupedMints.map((mintUnit) => ({
key: mintUnit.unit,
title: getCurrency(mintUnit.unit).code,
}))
)
const renderScene = function ({ route }: { route: { key: string } }) {
const unitMints = groupedMints.find((mintUnit) => mintUnit.unit === route.key);
const renderUnitTabs = function ({ route }: { route: { key: string } }) {
const unitMints = groupedMints.find((mintUnit) => mintUnit.unit === route.key)
if (unitMints) {
return (
<View key={unitMints.unit}>
<UnitBalanceBlock
unitBalance={balances.unitBalances.find(balance => balance.unit === unitMints.unit)!}
<>
<View style={[
$headerContainer, {
backgroundColor: headerBg,
paddingTop: spacing.medium
}
]}>
<UnitBalanceBlock
unitBalance={balances.unitBalances.find(balance => balance.unit === unitMints.unit)!}
/>
<Pressable
onPress={toggleMintsModal}
>
<MintsByUnitSummary
mintsByUnit={unitMints}
navigation={navigation}
/>
<View style={$contentContainer}>
<MintsByUnitListItem
mintsByUnit={unitMints}
navigation={navigation}
/>
{transactionsStore.recentByUnit(unitMints.unit).length > 0 && unitMints.mints.length < 4 && (
<Card
ContentComponent={
<FlatList
data={transactionsStore.recentByUnit(unitMints.unit, maxTransactionsByUnit - unitMints.mints.length) as Transaction[]}
renderItem={({item, index}) => {
return (<TransactionListItem
key={item.id}
transaction={item}
isFirst={index === 0}
isTimeAgoVisible={true}
gotoTranDetail={() => gotoTranDetail(item.id!)}
/>)
}
}
// style={{ maxHeight: 300 - (mints.mints.length > 1 ? mints.mints.length * 38 : 0)}}
/>
}
style={[$card, {paddingTop: spacing.extraSmall}]}
</Pressable>
</View>
<View style={$contentContainer}>
{transactionsStore.recentByUnit(unitMints.unit).length > 0 ? (
<Card
ContentComponent={
<FlatList
data={transactionsStore.recentByUnit(unitMints.unit, maxTransactionsByUnit) as Transaction[]}
renderItem={({item, index}) => {
return (
<TransactionListItem
key={item.id}
transaction={item}
isFirst={index === 0}
isTimeAgoVisible={true}
gotoTranDetail={() => gotoTranDetail(item.id!)}
/>
)}
}
/>
}
style={[$card, {paddingTop: spacing.extraSmall}]}
/>
) : (
<Card
ContentComponent={
<ListItem
leftIcon='faArrowTurnDown'
text='Make your first transaction'
textStyle={{fontSize: moderateScale(14)}}
/>
)}
</View>
</View>
}
style={[$card, {paddingTop: spacing.extraSmall, minHeight: 80}]}
/>
)}
</View>
</>
)
}
return null;
@@ -419,24 +492,40 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
const tabWidth = moderateScale(80)
const renderTabBar = (props: any) => (
<View style={{backgroundColor: headerBg, marginTop: -spacing.extraSmall}}>
<View style={{width: routes.length * tabWidth, alignSelf: 'center', backgroundColor: headerBg}}>
<TabBar
key={props.key}
{...props}
tabStyle={{width: tabWidth}}
indicatorStyle={{ backgroundColor: activeTabIndicator }}
style={{backgroundColor: headerBg, shadowColor: 'transparent'}}
/>
const getActiveTabColor = (state: NavigationState<Route>) => {
switch (state.routes[tabIndex].key) {
case 'usd':
return useThemeColor('usd')
case 'eur':
return useThemeColor('eur')
default:
return useThemeColor('btc')
}
}
const renderTabBar = (props: any) => {
return(
<View style={{backgroundColor: headerBg, marginTop: -spacing.extraSmall}}>
<View style={{width: routes.length * tabWidth, alignSelf: 'center', backgroundColor: headerBg}}>
<TabBar
{...props}
tabStyle={{width: tabWidth}}
renderLabel={({ route, focused, color }) => (
<CurrencySign
mintUnit={route.key as MintUnit}
containerStyle={focused ? {} : {opacity: 0.5}}
/>
)}
indicatorStyle={{ backgroundColor: getActiveTabColor(props.navigationState) }}
style={{backgroundColor: headerBg, shadowColor: 'transparent'}}
/>
</View>
</View>
</View>
)
const [index, setIndex] = useState(0)
const headerBg = useThemeColor('header')
const activeTabIndicator = colors.palette.accent400
)
}
const headerBg = useThemeColor('header')
const balances = proofsStore.getBalances()
const screenBg = useThemeColor('background')
const mainButtonIcon = useThemeColor('button')
@@ -481,10 +570,10 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
) : (
<TabView
renderTabBar={renderTabBar}
navigationState={{ index, routes }}
renderScene={renderScene}
onIndexChange={setIndex}
initialLayout={{ width: routes.length * 100 }}
navigationState={{ index: tabIndex, routes }}
renderScene={renderUnitTabs}
onIndexChange={onTabChange}
initialLayout={{ width: spacing.screenWidth }}
/>
)}
<View style={$bottomContainer}>
@@ -535,9 +624,24 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
{error && <ErrorModal error={error} />}
{isLoading && <Loading />}
<BottomModal
isVisible={isUpdateModalVisible ? true : false}
style={{alignItems: 'stretch'}}
ContentComponent={
isVisible={isMintsModalVisible ? true : false}
style={{alignItems: 'stretch', padding: spacing.medium}}
ContentComponent={
<MintsByUnitList
mintsByUnit={groupedMints}
currentUnit={currentUnit}
onTopup={gotoTopup}
onLightningPay={gotoLightningPay}
onMintInfo={gotoMintInfo}
/>
}
onBackButtonPress={toggleMintsModal}
onBackdropPress={toggleMintsModal}
/>
<BottomModal
isVisible={isUpdateModalVisible ? true : false}
style={{alignItems: 'stretch'}}
ContentComponent={
<ListItem
LeftComponent={
<View style={{marginRight: spacing.medium}}>
@@ -551,9 +655,9 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
subTx="updateModal.desc"
onPress={gotoUpdate}
/>
}
onBackButtonPress={toggleUpdateModal}
onBackdropPress={toggleUpdateModal}
}
onBackButtonPress={toggleUpdateModal}
onBackdropPress={toggleUpdateModal}
/>
<BottomModal
isVisible={isSendModalVisible ? true : false}
@@ -571,7 +675,7 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
leftIcon='faBolt'
tx="walletScreen.payWithLightning"
subTx="walletScreen.payWithLightningDesc"
onPress={gotoLightningPay}
onPress={() => gotoLightningPay()}
/>
</>
}
@@ -594,7 +698,7 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
leftIcon='faBolt'
tx='walletScreen.topupWithLightning'
subTx="walletScreen.topupWithLightningDesc"
onPress={gotoTopup}
onPress={() => gotoTopup()}
/>
</>
}
@@ -610,26 +714,32 @@ export const WalletScreen: FC<WalletScreenProps> = observer(
const UnitBalanceBlock = observer(function (props: {
unitBalance: UnitBalance
}) {
const headerBg = useThemeColor('header')
}) {
const balanceColor = 'white'
const currencyColor = colors.palette.primary200
const convertedBalanceColor = colors.palette.primary200
const currencyColor = colors.palette.primary200
const {unitBalance} = props
// const headerBg = getMintColor(unitBalance.unit)
// log.trace('[UnitBalanceBlock]', {unitBalance})
return (
<View style={[$headerContainer, {backgroundColor: headerBg, paddingTop: spacing.medium}]}>
<>
<CurrencyAmount
amount={unitBalance.unitBalance || 0}
// amount={2487}
mintUnit={unitBalance.unit}
symbolStyle={{fontSize: moderateVerticalScale(14), color: currencyColor, marginTop: spacing.small}}
amountStyle={[$unitBalance, {color: balanceColor, marginTop: spacing.small}]}
containerStyle={{marginLeft: -spacing.medium}}
symbolStyle={{display: 'none'}}
amountStyle={[$unitBalance, {color: balanceColor}]}
containerStyle={{marginTop: spacing.medium}}
/>
</View>
<CurrencyAmount
amount={283}
mintUnit={'usd'}
symbolStyle={{color: currencyColor, marginTop: spacing.tiny}}
amountStyle={{color: convertedBalanceColor}}
// containerStyle={{marginLeft: -spacing.medium}}
size='small'
/>
</>
)
})
@@ -700,10 +810,64 @@ const PromoBlock = function (props: {addMint: any}) {
}
const MintsByUnitListItem = observer(function (props: {
const MintsByUnitSummary = observer(function (props: {
mintsByUnit: MintsByUnit
navigation: any
}) {
const {
mintsStore,
proofsStore,
} = useStores()
const [selectedMint, setSelectedMint] = useState<Mint | undefined>(undefined)
useEffect(() => {
const setSelected = async () => {
const balance = proofsStore.getMintBalanceWithMaxBalance(props.mintsByUnit.unit)
if(!balance) return
const mint = mintsStore.findByUrl(balance?.mintUrl)
setSelectedMint(mint)
}
setSelected()
return () => {}
}, [])
const {mintsByUnit} = props
const mintsCountText = `and ${mintsByUnit.mints.length} other${mintsByUnit.mints.length > 1 && 's'}`
return (
<View style={{flexDirection: 'row', alignItems: 'center', marginTop: spacing.small}}>
<View
style={{
marginEnd: spacing.small,
flex: 0,
borderRadius: spacing.small,
padding: spacing.extraSmall,
backgroundColor: getMintColor(mintsByUnit.unit)
}}
>
<SvgXml
width={spacing.medium}
height={spacing.medium}
xml={MintIcon}
fill='white'
/>
</View>
<Text size='xs' style={{color: 'white'}} text={`${selectedMint?.shortname} ${mintsByUnit.mints.length > 1 ? mintsCountText : ''}`}/>
</View>
)
})
const MintsByUnitList = observer(function (props: {
mintsByUnit: MintsByUnit[]
currentUnit: MintUnit
onTopup: Function
onLightningPay: Function
onMintInfo: Function
}) {
const [selectedMintUrl, setSelectedMintUrl] = useState<string | undefined>(undefined)
@@ -717,153 +881,113 @@ const MintsByUnitListItem = observer(function (props: {
LayoutAnimation.easeInEaseOut()
setSelectedMintUrl(mintUrl)
}
const gotoMintInfo = function (mintUrl: string) {
props.navigation.navigate('SettingsNavigator', {screen: 'MintInfo', params: {mintUrl}, initial: false})
}
const gotoTopup = function (unit: MintUnit, mintUrl: string) {
props.navigation.navigate('Topup', {
mintUrl,
unit
})
}
const gotoLightningPay = async function (unit: MintUnit, mintUrl: string, ) {
props.navigation.navigate('LightningPay', {
mintUrl,
unit
})
}
const gotoSend = async function (unit: MintUnit, mintUrl: string) {
props.navigation.navigate('Send', {
mintUrl,
unit
})
}
const color = useThemeColor('textDim')
const balanceColor = useThemeColor('amount')
const {mintsByUnit} = props
/* const isSingleMint: boolean = mintsByUnit.mints.length === 1 || false
const singleMint: Mint = mintsByUnit.mints[0] */
const mintsByUnitCurrent = mintsByUnit.find((mintUnit) => mintUnit.unit === props.currentUnit)
return (
<Card
verticalAlignment='force-footer-bottom'
ContentComponent={
<ScrollView>
{mintsByUnit.mints.map((mint: Mint) => (
<View key={mint.mintUrl}>
<ListItem
text={mint.shortname}
subText={mint.hostname}
LeftComponent={
<View
style={{
marginEnd: spacing.small,
flex: 0,
borderRadius: spacing.small,
padding: spacing.extraSmall,
backgroundColor: getMintColor(mintsByUnit.unit)
}}
>
<>
{mintsByUnitCurrent!.mints.map((mint: Mint, index: number) => (
<View key={mint.mintUrl}>
<ListItem
text={mint.shortname}
subText={mint.hostname}
LeftComponent={
<View
style={{
marginEnd: spacing.small,
flex: 0,
borderRadius: spacing.small,
padding: spacing.extraSmall,
backgroundColor: getMintColor(mintsByUnitCurrent!.unit)
}}
>
<SvgXml
width={spacing.medium}
height={spacing.medium}
xml={MintIcon}
fill='white'
/>
</View>
}
RightComponent={
<CurrencyAmount
amount={mint.balances?.balances[mintsByUnitCurrent!.unit] || 0}
mintUnit={mintsByUnitCurrent!.unit}
size='medium'
/>
}
//topSeparator={true}
style={$item}
onPress={() => onSelectedMint(mint.mintUrl)}
topSeparator={index !== 0 ?? true}
/>
{selectedMintUrl === mint.mintUrl && (
<View style={{flexDirection: 'row', marginBottom: spacing.small, justifyContent: 'flex-start'}}>
<Button
tx="walletScreen.topup"
LeftAccessory={() => (
<Icon
icon='faPlus'
color={color}
size={spacing.small}
/>
)}
preset='secondary'
textStyle={{fontSize: 14, color}}
onPress={() => props.onTopup(mintsByUnitCurrent!.unit, mint.mintUrl)}
style={{
minHeight: moderateVerticalScale(40),
paddingVertical: moderateVerticalScale(spacing.tiny),
marginRight: spacing.small
}}
/>
<Button
tx="walletScreen.pay"
LeftAccessory={() => (
<Icon
icon='faBolt'
color={color}
size={spacing.small}
/>
)}
textStyle={{fontSize: 14, color}}
preset='secondary'
onPress={() => props.onLightningPay(mintsByUnitCurrent!.unit, mint.mintUrl)}
style={{
minHeight: moderateVerticalScale(40),
paddingVertical: moderateVerticalScale(spacing.tiny),
marginRight: spacing.small
}}
/>
<Button
tx="wallerScreen.mintButton"
LeftAccessory={() => (
<View style={{marginHorizontal: spacing.extraSmall}}>
<SvgXml
width={spacing.medium}
height={spacing.medium}
width={spacing.small}
height={spacing.small}
xml={MintIcon}
fill='white'
fill={color}
/>
</View>
}
RightComponent={
<CurrencyAmount
amount={mint.balances?.balances[mintsByUnit.unit as MintUnit] || 0}
mintUnit={mintsByUnit.unit}
size='medium'
/>
}
//topSeparator={true}
style={$item}
onPress={() => onSelectedMint(mint.mintUrl)}
)}
textStyle={{fontSize: 14, color}}
preset='secondary'
onPress={() => props.onMintInfo(mint.mintUrl)}
style={{
minHeight: moderateVerticalScale(40),
paddingVertical: moderateVerticalScale(spacing.tiny),
marginRight: spacing.small
}}
/>
{selectedMintUrl === mint.mintUrl && (
<View style={{flexDirection: 'row', marginBottom: spacing.small, justifyContent: 'flex-start'}}>
<Button
tx="walletScreen.topup"
LeftAccessory={() => (
<Icon
icon='faPlus'
color={color}
size={spacing.small}
/>
)}
preset='secondary'
textStyle={{fontSize: 14, color}}
onPress={() => gotoTopup(mintsByUnit.unit, mint.mintUrl)}
style={{
minHeight: moderateVerticalScale(40),
paddingVertical: moderateVerticalScale(spacing.tiny),
marginRight: spacing.small
}}
/>
<Button
tx="walletScreen.pay"
LeftAccessory={() => (
<Icon
icon='faBolt'
color={color}
size={spacing.small}
/>
)}
textStyle={{fontSize: 14, color}}
preset='secondary'
onPress={() => gotoLightningPay(mintsByUnit.unit, mint.mintUrl)}
style={{
minHeight: moderateVerticalScale(40),
paddingVertical: moderateVerticalScale(spacing.tiny),
marginRight: spacing.small
}}
/>
<Button
tx="wallerScreen.mintButton"
LeftAccessory={() => (
<View style={{marginHorizontal: spacing.extraSmall}}>
<SvgXml
width={spacing.small}
height={spacing.small}
xml={MintIcon}
fill={color}
/>
</View>
)}
textStyle={{fontSize: 14, color}}
preset='secondary'
onPress={() => gotoMintInfo(mint.mintUrl)}
style={{
minHeight: moderateVerticalScale(40),
paddingVertical: moderateVerticalScale(spacing.tiny),
marginRight: spacing.small
}}
/>
</View>
)}
</View>
))}
</ScrollView>
}
contentStyle={{color}}
style={[$card, {maxHeight: spacing.screenHeight * 0.6}]}
/>
</View>
)}
</View>
))}
</>
)
})
@@ -895,11 +1019,12 @@ const $headerContainer: TextStyle = {
}
const $contentContainer: TextStyle = {
marginTop: -spacing.extraLarge * 2,
marginTop: -spacing.extraLarge * 1.5,
// alignSelf: 'stretch',
// padding: spacing.extraSmall,
// flex: 1,
// paddingTop: spacing.extraSmall - 3,
// borderWidth: 5,
// borderWidth: 3,
// borderColor: 'green',
}
+6 -6
View File
@@ -172,14 +172,11 @@ export const colors = {
statusBarOnModalOpen: '#214D96',
statusBarOnLoading: '#346BC6',
loadingIndicator: '#fff',
btc: '#f7931A',
usd: '#599D52',
eur: '#0002C8'
},
dark: {
/**
* The palette is available to use, but prefer using the name.
* This is only included for rare, one-off cases. Try to use
* semantic names as much as possible.
*/
palette,
/**
* A helper for making something see-thru.
*/
@@ -274,6 +271,9 @@ export const colors = {
statusBarOnModalOpen: '#162F83',
statusBarOnLoading: '#2746B0',
loadingIndicator: '#ccc',
btc: '#f7931A',
usd: '#599D52',
eur: '#0002C8'
},
}
+8 -1
View File
@@ -3518,13 +3518,20 @@ __metadata:
languageName: node
linkType: hard
"@scure/base@npm:~1.1.0, @scure/base@npm:~1.1.7, @scure/base@npm:~1.1.8":
"@scure/base@npm:~1.1.0":
version: 1.1.8
resolution: "@scure/base@npm:1.1.8"
checksum: 1fc8a355ba68663c0eb430cf6a2c5ff5af790c347c1ba1953f344e8681ab37e37e2545e495f7f971b0245727d710fea8c1e57d232d0c6c543cbed4965c7596a1
languageName: node
linkType: hard
"@scure/base@npm:~1.1.7, @scure/base@npm:~1.1.8":
version: 1.1.9
resolution: "@scure/base@npm:1.1.9"
checksum: 120820a37dfe9dfe4cab2b7b7460552d08e67dee8057ed5354eb68d8e3440890ae983ce3bee957d2b45684950b454a2b6d71d5ee77c1fd3fddc022e2a510337f
languageName: node
linkType: hard
"@scure/bip32@npm:1.3.1":
version: 1.3.1
resolution: "@scure/bip32@npm:1.3.1"