@@ -24,7 +24,7 @@ import { useDispatch, useSelector } from '../../types/reactRedux'
2424import type { BuyTabSceneProps , NavigationBase } from '../../types/routerTypes'
2525import type { GuiFiatType } from '../../types/types'
2626import { getCurrencyCode } from '../../util/CurrencyInfoHelpers'
27- import { DECIMAL_PRECISION } from '../../util/utils'
27+ import { DECIMAL_PRECISION , mulToPrecision } from '../../util/utils'
2828import { DropDownInputButton } from '../buttons/DropDownInputButton'
2929import { PillButton } from '../buttons/PillButton'
3030import { AlertCardUi4 } from '../cards/AlertCard'
@@ -69,6 +69,7 @@ export const TradeCreateScene: React.FC<Props> = (props: Props) => {
6969 const [ lastUsedInput , setLastUsedInput ] = useState < 'fiat' | 'crypto' | null > (
7070 null
7171 )
72+ const [ isMaxAmount , setIsMaxAmount ] = useState ( false )
7273
7374 // Selected currencies
7475 const defaultFiat = useSelector ( state => getDefaultFiat ( state ) )
@@ -194,7 +195,7 @@ export const TradeCreateScene: React.FC<Props> = (props: Props) => {
194195 selectedWallet == null ||
195196 selectedCryptoCurrencyCode == null ||
196197 lastUsedInput == null ||
197- userInput === '' ||
198+ ( userInput === '' && ! isMaxAmount ) ||
198199 countryCode === ''
199200 ) {
200201 return null
@@ -205,7 +206,7 @@ export const TradeCreateScene: React.FC<Props> = (props: Props) => {
205206 pluginId : selectedWallet . currencyInfo . pluginId ,
206207 tokenId : selectedCrypto ?. tokenId ?? null ,
207208 displayCurrencyCode : selectedCryptoCurrencyCode ,
208- exchangeAmount : userInput ,
209+ exchangeAmount : isMaxAmount ? { max : true } : userInput ,
209210 fiatCurrencyCode : selectedFiatCurrencyCode ,
210211 amountType : lastUsedInput ,
211212 direction : 'buy' ,
@@ -219,6 +220,7 @@ export const TradeCreateScene: React.FC<Props> = (props: Props) => {
219220 selectedCryptoCurrencyCode ,
220221 selectedCrypto ,
221222 userInput ,
223+ isMaxAmount ,
222224 selectedFiatCurrencyCode ,
223225 lastUsedInput ,
224226 countryCode ,
@@ -285,7 +287,9 @@ export const TradeCreateScene: React.FC<Props> = (props: Props) => {
285287 if ( fiatAmt === '' || quoteExchangeRate === 0 ) return ''
286288
287289 const decimals =
288- denomination ?. multiplier . match ( / 0 / g) ?. length ?? DECIMAL_PRECISION
290+ denomination != null
291+ ? mulToPrecision ( denomination . multiplier )
292+ : DECIMAL_PRECISION
289293 try {
290294 return div ( fiatAmt , quoteExchangeRate . toString ( ) , decimals )
291295 } catch {
@@ -297,6 +301,9 @@ export const TradeCreateScene: React.FC<Props> = (props: Props) => {
297301
298302 // Derived state for display values
299303 const displayFiatAmount = React . useMemo ( ( ) => {
304+ if ( isMaxAmount && bestQuote != null ) {
305+ return bestQuote . fiatAmount
306+ }
300307 if ( userInput === '' || lastUsedInput === null ) return ''
301308
302309 if ( lastUsedInput === 'fiat' ) {
@@ -305,9 +312,12 @@ export const TradeCreateScene: React.FC<Props> = (props: Props) => {
305312 // User entered crypto, convert to fiat only if we have a quote
306313 return convertCryptoToFiat ( userInput )
307314 }
308- } , [ userInput , lastUsedInput , convertCryptoToFiat ] )
315+ } , [ userInput , lastUsedInput , convertCryptoToFiat , isMaxAmount , bestQuote ] )
309316
310317 const displayCryptoAmount = React . useMemo ( ( ) => {
318+ if ( isMaxAmount && bestQuote != null ) {
319+ return bestQuote . cryptoAmount
320+ }
311321 if ( userInput === '' || lastUsedInput === null ) return ''
312322
313323 if ( lastUsedInput === 'crypto' ) {
@@ -316,7 +326,7 @@ export const TradeCreateScene: React.FC<Props> = (props: Props) => {
316326 // User entered fiat, convert to crypto only if we have a quote
317327 return convertFiatToCrypto ( userInput )
318328 }
319- } , [ userInput , lastUsedInput , convertFiatToCrypto ] )
329+ } , [ userInput , lastUsedInput , convertFiatToCrypto , isMaxAmount , bestQuote ] )
320330
321331 //
322332 // Handlers
@@ -375,7 +385,7 @@ export const TradeCreateScene: React.FC<Props> = (props: Props) => {
375385 selectedWallet == null ||
376386 selectedCryptoCurrencyCode == null ||
377387 lastUsedInput == null ||
378- userInput === '' ||
388+ ( userInput === '' && ! isMaxAmount ) ||
379389 rampQuoteRequest == null
380390 ) {
381391 return
@@ -396,17 +406,29 @@ export const TradeCreateScene: React.FC<Props> = (props: Props) => {
396406 } , [ selectedCryptoCurrencyCode , quoteExchangeRate , selectedFiatCurrencyCode ] )
397407
398408 const handleFiatChangeText = useHandler ( ( text : string ) => {
409+ setIsMaxAmount ( false )
399410 setUserInput ( text )
400411 setLastUsedInput ( 'fiat' )
401412 } )
402413
403414 const handleCryptoChangeText = useHandler ( ( text : string ) => {
415+ setIsMaxAmount ( false )
404416 setUserInput ( text )
405417 setLastUsedInput ( 'crypto' )
406418 } )
407419
408420 const handleMaxPress = useHandler ( ( ) => {
409- // TODO: Implement max functionality
421+ if ( isMaxAmount ) {
422+ // Toggle off max mode
423+ setIsMaxAmount ( false )
424+ setUserInput ( '' )
425+ // Keep lastUsedInput as is so the UI remains focused on the same field
426+ } else {
427+ // Toggle on max mode
428+ setIsMaxAmount ( true )
429+ setLastUsedInput ( 'fiat' )
430+ setUserInput ( '' ) // Clear input when using max
431+ }
410432 } )
411433
412434 // Render region selection view
@@ -531,9 +553,7 @@ export const TradeCreateScene: React.FC<Props> = (props: Props) => {
531553 { /* Bottom Input (Crypto by design) */ }
532554 < InputRow >
533555 < DropDownInputButton onPress = { handleCryptDropdown } >
534- { selectedCrypto == null || selectedWallet == null ? (
535- < FlagIcon sizeRem = { 1.5 } source = { { uri : '' } } />
536- ) : (
556+ { selectedCrypto == null || selectedWallet == null ? null : (
537557 < CryptoIcon
538558 sizeRem = { 1.5 }
539559 pluginId = { selectedWallet ?. currencyInfo . pluginId ?? '' }
@@ -566,7 +586,7 @@ export const TradeCreateScene: React.FC<Props> = (props: Props) => {
566586 { selectedCrypto == null ||
567587 selectedWallet == null ||
568588 denomination == null ||
569- userInput === '' ||
589+ ( userInput === '' && ! isMaxAmount ) ||
570590 lastUsedInput == null ||
571591 ( ! isLoadingQuotes && sortedQuotes . length === 0 ) ? null : (
572592 < ExchangeRateContainer >
@@ -608,7 +628,8 @@ export const TradeCreateScene: React.FC<Props> = (props: Props) => {
608628 supportedPluginsError != null &&
609629 quoteErrors . length > 0 &&
610630 sortedQuotes . length === 0 &&
611- supportedPlugins . length > 0 ? (
631+ supportedPlugins . length > 0 &&
632+ ( userInput !== '' || isMaxAmount ) ? (
612633 < AlertCardUi4
613634 type = "error"
614635 title = { lstrings . trade_buy_unavailable_title }
@@ -629,7 +650,7 @@ export const TradeCreateScene: React.FC<Props> = (props: Props) => {
629650 disabled = {
630651 selectedWallet == null ||
631652 selectedCryptoCurrencyCode == null ||
632- userInput === '' ||
653+ ( userInput === '' && ! isMaxAmount ) ||
633654 lastUsedInput === null ||
634655 isPluginsLoading ||
635656 isCheckingSupport ||
@@ -662,10 +683,16 @@ const InputRow = styled(View)(theme => ({
662683 gap : theme . rem ( 1 )
663684} ) )
664685
665- const MaxButton = styled ( EdgeTouchableOpacity ) ( theme => ( {
666- alignSelf : 'flex-end' ,
667- padding : theme . rem ( 0.5 )
668- } ) )
686+ const MaxButton = styled ( EdgeTouchableOpacity ) < { active ?: boolean } > (
687+ theme => props => ( {
688+ alignSelf : 'flex-end' ,
689+ padding : theme . rem ( 0.25 ) ,
690+ margin : theme . rem ( 0.25 ) ,
691+ borderWidth : 1 ,
692+ borderRadius : theme . rem ( 0.5 ) ,
693+ borderColor : props . active === true ? theme . escapeButtonText : 'transparent'
694+ } )
695+ )
669696
670697const MaxButtonText = styled ( Text ) ( theme => ( {
671698 color : theme . escapeButtonText ,
0 commit comments