diff --git a/src/App.css b/src/App.css index 7af9e30..e5a4c6d 100644 --- a/src/App.css +++ b/src/App.css @@ -36,6 +36,11 @@ cursor: pointer; } +.buy-modal { + top: 30%!important; + width: auto!important; +} + /* Remove input number arrows Chrome, Safari, Edge, Opera */ input::-webkit-outer-spin-button, diff --git a/src/App.js b/src/App.js index 49a0139..f437617 100644 --- a/src/App.js +++ b/src/App.js @@ -73,16 +73,16 @@ function App (props) { // Load the P2WDB libraries. addToModal('Loading P2WDB Libraries', appData) - const {p2wdbRead, p2wdbWrite} = asyncLoad.getP2WDBLib({bchWallet: walletTemp}) + const { p2wdbRead, p2wdbWrite } = asyncLoad.getP2WDBLib({ bchWallet: walletTemp }) // Load the DEX library. addToModal('Loading DEX Library', appData) - const dexLib = asyncLoad.getDexLib({bchWallet: walletTemp, p2wdbRead, p2wdbWrite}) + const dexLib = asyncLoad.getDexLib({ bchWallet: walletTemp, p2wdbRead, p2wdbWrite }) appData.setDexLib(dexLib) // Load the Nostr library. addToModal('Loading Nostr Library', appData) - const nostrLib = asyncLoad.getNostrLib({bchWallet: walletTemp}) + const nostrLib = asyncLoad.getNostrLib({ bchWallet: walletTemp }) appData.setNostr(nostrLib) // Update state diff --git a/src/components/app-body/nfts-for-sale/buy-button.js b/src/components/app-body/nfts-for-sale/buy-button.js index 2b3c8b1..8ef765a 100644 --- a/src/components/app-body/nfts-for-sale/buy-button.js +++ b/src/components/app-body/nfts-for-sale/buy-button.js @@ -5,49 +5,86 @@ // Global npm libraries import React, { useState } from 'react' -import { Button, Modal, Container, Row, Col } from 'react-bootstrap' +import { Button, Modal, Container, Row, Col, Spinner } from 'react-bootstrap' function BuyButton (props) { - const { token, appData } = props - - const [show, setShow] = useState(false) + const { token, appData, onSuccess } = props + console.log('props: ', props) + const [show, setShow] = useState(false) // show the modal + const [onFetch, setOnFetch] = useState(false) // show the spinner + const [error, setError] = useState(false) // show the error message + // const [eventId, setEventId] = useState(false) // show the event id + const [noteId, setNoteId] = useState(false) // show the note id + const [success, setSuccess] = useState(false) // show the success message + const [showConfirmation, setShowConfirmation] = useState(true) // show the confirmation view const handleBuy = async () => { - console.log('handleBuy()') - console.log('token: ', token) - console.log('appData: ', appData) + try { + console.log('handleBuy()') + console.log('token: ', token) + console.log('appData: ', appData) + setShowConfirmation(false) + setOnFetch(true) - const targetOffer = token.nostrEventId - console.log('targetOffer: ', targetOffer) + /* // dev-test success view + setShowConfirmation(false) + setSuccess(true) + setNoteId('note12986q83gre76vl9dldpnnhej7y67h76xzw0tx0hm4mq6uradr6lskch7v9') + setOnFetch(false) + return + */ + const targetOffer = token.nostrEventId + console.log('targetOffer: ', targetOffer) - // TODO: Launch modal to let user know that the purchase is in progress. + // Generate a counter offer. + const bchDexLib = appData.dexLib + const { offerData, partialHex } = await bchDexLib.take.takeOffer( + targetOffer + ) - // Generate a counter offer. - const bchDexLib = appData.dexLib - const { offerData, partialHex } = await bchDexLib.take.takeOffer(targetOffer) + console.log('offerData: ', offerData) + console.log('partialHex: ', partialHex) - console.log('offerData: ', offerData) - console.log('partialHex: ', partialHex) + // Upload the counter offer to Nostr. + const nostr = appData.nostr + const { eventId, noteId } = await nostr.testNostrUpload({ + offerData, + partialHex + }) - // Upload the counter offer to Nostr. - const nostr = appData.nostr - const { eventId, noteId } = await nostr.testNostrUpload({ offerData, partialHex }) + console.log( + `Counter Offer uploaded to Nostr with this event ID: ${eventId}` + ) + console.log(`https://astral.psfoundation.info/${noteId}`) - console.log(`Counter Offer uploaded to Nostr with this event ID: ${eventId}`) - console.log(`https://astral.psfoundation.info/${noteId}`) + setNoteId(noteId) + setSuccess(true) + setOnFetch(false) + } catch (error) { + setOnFetch(false) + setError(error.message) + } } const handleClose = () => { console.log('handleClose()') + // Deny close if the purchase is in progress. + if (onFetch) { + return + } + + // Call onSuccess() callback if the modal close after a success purchase. + if (success && onSuccess) { + onSuccess() + } + // Reset the state. + setError(false) + setSuccess(false) + setNoteId(false) setShow(false) - // props.instance.setState({ showModal: false }) + setOnFetch(false) + setShowConfirmation(true) } - - const handleOpen = () => { - console.log('handleOpen()') - setShow(true) - } - // Replace with dummy button until token data is loaded. if (!props.token.tokenData) { return ( @@ -59,45 +96,94 @@ function BuyButton (props) { return ( <> - Buy - + { + setShow(true) + }} + > + Buy + + - Token Information + + {success + ? ( + Successful Purchase + ) + : ( + 'Processing Purchase' + )} + - - - - Ticker: - {props.token.ticker} - + + {/** If the purchase is not confirmed, display the token details. and confirm button. */} + {showConfirmation && ( + + + + Ticker: + + {token.ticker} + - - Name: - {props.token.tokenData.genesisData.name} - + + + Name: + + {props.token.tokenData.genesisData.name} + + + + Price: + + + {token.usdPrice} + + + + )} - - Token ID: - - - {props.token.tokenId} - - - - - - Decimals: - {props.token.tokenData.genesisData.decimals} - - - - Token Type: - {props.token.tokenType} - + {/** show purchase progress */} + + {onFetch && } + {error && ( + {error} + )} + {success && ( + <> + + Note ID : + + {' '} + {noteId} + + + > + )} - + + {showConfirmation && ( + + + + Buy + + + + )} + > ) diff --git a/src/components/app-body/nfts-for-sale/index.js b/src/components/app-body/nfts-for-sale/index.js index d5416b4..82d9095 100644 --- a/src/components/app-body/nfts-for-sale/index.js +++ b/src/components/app-body/nfts-for-sale/index.js @@ -205,7 +205,7 @@ function NftsForSale (props) { } return url } - + // This function generates a Token Card for each token in the wallet. function generateCards (offers) { console.log('generateCards() offerData: ', offers) @@ -221,6 +221,7 @@ function NftsForSale (props) { ) diff --git a/src/components/app-body/nfts-for-sale/token-card.js b/src/components/app-body/nfts-for-sale/token-card.js index a1ea09b..91b5b1b 100644 --- a/src/components/app-body/nfts-for-sale/token-card.js +++ b/src/components/app-body/nfts-for-sale/token-card.js @@ -12,7 +12,7 @@ import InfoButton from './info-button' import BuyButton from './buy-button' function TokenCard (props) { - const { token, appData } = props + const { token, appData, handleRefresh } = props const [icon, setIcon] = useState(token.icon) const [tokenData, setTokenData] = useState(token.tokenData) @@ -72,7 +72,7 @@ function TokenCard (props) { - + diff --git a/src/services/async-load.js b/src/services/async-load.js index f8c321f..3e7b8b6 100644 --- a/src/services/async-load.js +++ b/src/services/async-load.js @@ -205,7 +205,7 @@ class AsyncLoad { try { const { bchWallet, p2wdbRead, p2wdbWrite } = inObj - const dexLib = new BchDexLib({bchWallet, p2wdbRead, p2wdbWrite}) + const dexLib = new BchDexLib({ bchWallet, p2wdbRead, p2wdbWrite }) return dexLib } catch (error) { @@ -219,7 +219,7 @@ class AsyncLoad { try { const { bchWallet } = inObj - const nostrLib = new Nostr({bchWallet}) + const nostrLib = new Nostr({ bchWallet }) return nostrLib } catch (error) { @@ -234,9 +234,9 @@ class AsyncLoad { const { bchWallet } = inObj const p2wdbRead = new P2WDB.Read() - const p2wdbWrite = new P2WDB.Write({bchWallet}) + const p2wdbWrite = new P2WDB.Write({ bchWallet }) - return {p2wdbRead, p2wdbWrite} + return { p2wdbRead, p2wdbWrite } } catch (error) { console.error('Error in getP2WDBLib', error) throw error @@ -244,8 +244,6 @@ class AsyncLoad { } } - - function sleep (ms) { return new Promise(resolve => setTimeout(resolve, ms)) }
+ Note ID : + + {' '} + {noteId} + +