2022-01-08 13:08:03 +00:00
import React , { Component } from "react" ;
2022-04-05 14:25:53 +00:00
import { withTranslation , Trans } from "react-i18next" ;
2022-03-24 22:18:01 +00:00
import { IconButton , Box , Link , Paper , Rating , Button , Tooltip , CircularProgress , Grid , Typography , TextField , List , ListItem , ListItemText , Divider , ListItemIcon , Dialog , DialogActions , DialogContent , DialogContentText , DialogTitle } from "@mui/material"
2022-01-09 01:23:13 +00:00
import QRCode from "react-qr-code" ;
2022-02-04 18:07:09 +00:00
import Countdown , { zeroPad } from 'react-countdown' ;
2022-01-13 19:22:54 +00:00
import Chat from "./Chat"
2022-01-27 22:51:57 +00:00
import MediaQuery from 'react-responsive'
2022-01-28 00:17:20 +00:00
import QrReader from 'react-qr-reader'
2022-01-13 19:22:54 +00:00
2022-01-14 13:31:54 +00:00
// Icons
import PercentIcon from '@mui/icons-material/Percent' ;
import BookIcon from '@mui/icons-material/Book' ;
2022-01-28 00:17:20 +00:00
import QrCodeScannerIcon from '@mui/icons-material/QrCodeScanner' ;
2022-02-22 00:50:25 +00:00
import SendIcon from '@mui/icons-material/Send' ;
2022-03-11 14:33:07 +00:00
import LockIcon from '@mui/icons-material/Lock' ;
import LockOpenIcon from '@mui/icons-material/LockOpen' ;
import BalanceIcon from '@mui/icons-material/Balance' ;
import ContentCopy from "@mui/icons-material/ContentCopy" ;
2022-01-14 13:31:54 +00:00
2022-04-15 16:22:49 +00:00
import { getCookie } from "../utils/cookies" ;
2022-04-20 19:32:41 +00:00
import { pn } from "../utils/prettyNumbers" ;
2022-01-09 01:23:13 +00:00
2022-04-05 14:25:53 +00:00
class TradeBox extends Component {
2022-04-15 23:26:39 +00:00
invoice _escrow _duration = 3 ;
2022-01-09 14:07:05 +00:00
constructor ( props ) {
super ( props ) ;
2022-01-11 01:02:06 +00:00
this . state = {
2022-01-17 23:11:41 +00:00
openConfirmFiatReceived : false ,
openConfirmDispute : false ,
2022-02-22 10:34:48 +00:00
openEnableTelegram : false ,
2022-01-11 01:02:06 +00:00
badInvoice : false ,
2022-01-16 21:54:42 +00:00
badStatement : false ,
2022-01-28 00:17:20 +00:00
qrscanner : false ,
2022-01-11 01:02:06 +00:00
}
2022-01-09 01:23:13 +00:00
}
2022-01-17 23:11:41 +00:00
2022-04-15 16:22:49 +00:00
2022-04-05 14:25:53 +00:00
2022-01-23 12:30:41 +00:00
Sound = ( { soundFileName } ) => (
2022-03-08 20:15:27 +00:00
// Four filenames: "locked-invoice", "taker-found", "open-chat", "successful"
2022-01-23 12:30:41 +00:00
< audio autoPlay src = { ` /static/assets/sounds/ ${ soundFileName } .mp3 ` } / >
)
togglePlay = ( ) => {
this . setState ( { playSound : ! this . state . playSound } , ( ) => {
this . state . playSound ? this . audio . play ( ) : this . audio . pause ( ) ;
} ) ;
}
2022-03-11 14:33:07 +00:00
stepXofY = ( ) => {
// set y value
var x = null
var y = null
var status = this . props . data . status
if ( this . props . data . is _maker ) { y = 5 }
if ( this . props . data . is _taker ) { y = 4 }
// set x values
if ( this . props . data . is _maker ) {
if ( status == 0 ) {
x = 1
} else if ( [ 1 , 3 ] . includes ( status ) ) {
x = 2
} else if ( [ 6 , 7 , 8 ] . includes ( status ) ) {
x = 3
} else if ( status == 9 ) {
x = 4
} else if ( status == 10 ) {
x = 5
}
}
if ( this . props . data . is _taker ) {
if ( status == 3 ) {
x = 1
} else if ( [ 6 , 7 , 8 ] . includes ( status ) ) {
x = 2
} else if ( status == 9 ) {
x = 3
} else if ( status == 10 ) {
x = 4
}
}
// Return "(x/y)"
if ( x != null & y != null ) {
return "(" + x + "/" + y + ")"
} else {
return ''
}
}
2022-01-17 23:11:41 +00:00
handleClickOpenConfirmDispute = ( ) => {
this . setState ( { openConfirmDispute : true } ) ;
} ;
handleClickCloseConfirmDispute = ( ) => {
this . setState ( { openConfirmDispute : false } ) ;
} ;
handleClickAgreeDisputeButton = ( ) => {
const requestOptions = {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' , 'X-CSRFToken' : getCookie ( 'csrftoken' ) , } ,
body : JSON . stringify ( {
'action' : "dispute" ,
} ) ,
} ;
fetch ( '/api/order/' + '?order_id=' + this . props . data . id , requestOptions )
. then ( ( response ) => response . json ( ) )
2022-01-22 23:05:03 +00:00
. then ( ( data ) => this . props . completeSetState ( data ) ) ;
2022-01-17 23:11:41 +00:00
this . handleClickCloseConfirmDispute ( ) ;
}
ConfirmDisputeDialog = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-17 23:11:41 +00:00
return (
< Dialog
open = { this . state . openConfirmDispute }
onClose = { this . handleClickCloseConfirmDispute }
aria - labelledby = "open-dispute-dialog-title"
aria - describedby = "open-dispute-dialog-description"
>
< DialogTitle id = "open-dispute-dialog-title" >
2022-04-05 14:25:53 +00:00
{ t ( "Do you want to open a dispute?" ) }
2022-01-17 23:11:41 +00:00
< / D i a l o g T i t l e >
< DialogContent >
< DialogContentText id = "alert-dialog-description" >
2022-04-05 14:25:53 +00:00
{ t ( "The RoboSats staff will examine the statements and evidence provided. You need to build a complete case, as the staff cannot read the chat. It is best to provide a burner contact method with your statement. The satoshis in the trade escrow will be sent to the dispute winner, while the dispute loser will lose the bond." ) }
2022-01-17 23:11:41 +00:00
< / D i a l o g C o n t e n t T e x t >
< / D i a l o g C o n t e n t >
< DialogActions >
2022-04-05 14:25:53 +00:00
< Button onClick = { this . handleClickCloseConfirmDispute } autoFocus > { t ( "Disagree" ) } < / B u t t o n >
< Button onClick = { this . handleClickAgreeDisputeButton } > { t ( "Agree and open dispute" ) } < / B u t t o n >
2022-01-17 23:11:41 +00:00
< / D i a l o g A c t i o n s >
< / D i a l o g >
)
}
handleClickOpenConfirmFiatReceived = ( ) => {
this . setState ( { openConfirmFiatReceived : true } ) ;
} ;
handleClickCloseConfirmFiatReceived = ( ) => {
this . setState ( { openConfirmFiatReceived : false } ) ;
} ;
handleClickTotallyConfirmFiatReceived = ( ) => {
this . handleClickConfirmButton ( ) ;
this . handleClickCloseConfirmFiatReceived ( ) ;
} ;
ConfirmFiatReceivedDialog = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-04-24 15:18:17 +00:00
return (
2022-01-17 23:11:41 +00:00
< Dialog
open = { this . state . openConfirmFiatReceived }
onClose = { this . handleClickCloseConfirmFiatReceived }
aria - labelledby = "fiat-received-dialog-title"
aria - describedby = "fiat-received-dialog-description"
>
< DialogTitle id = "open-dispute-dialog-title" >
2022-04-05 14:25:53 +00:00
{ t ( "Confirm you received {{currencyCode}}?" , { currencyCode : this . props . data . currencyCode } ) }
2022-01-17 23:11:41 +00:00
< / D i a l o g T i t l e >
< DialogContent >
< DialogContentText id = "alert-dialog-description" >
2022-04-05 14:25:53 +00:00
{ t ( "Confirming that you received the fiat will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after the {{currencyCode}} has arrived to your account. In addition, if you have received {{currencyCode}} and do not confirm the receipt, you risk losing your bond." , { currencyCode : this . props . data . currencyCode } ) }
2022-01-17 23:11:41 +00:00
< / D i a l o g C o n t e n t T e x t >
< / D i a l o g C o n t e n t >
< DialogActions >
2022-04-05 14:25:53 +00:00
< Button onClick = { this . handleClickCloseConfirmFiatReceived } autoFocus > { t ( "Go back" ) } < / B u t t o n >
< Button onClick = { this . handleClickTotallyConfirmFiatReceived } > { t ( "Confirm" ) } < / B u t t o n >
2022-01-17 23:11:41 +00:00
< / D i a l o g A c t i o n s >
< / D i a l o g >
)
}
2022-01-09 12:14:11 +00:00
showQRInvoice = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-08 13:08:03 +00:00
return (
< Grid container spacing = { 1 } >
< Grid item xs = { 12 } align = "center" >
< Typography component = "body2" variant = "body2" >
2022-04-05 14:25:53 +00:00
{ t ( "Robots show commitment to their peers" ) }
2022-01-08 13:08:03 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "center" >
2022-01-22 23:05:03 +00:00
{ this . props . data . is _maker ?
2022-01-10 18:47:16 +00:00
< Typography color = "primary" component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b >
{ t ( "Lock {{amountSats}} Sats to PUBLISH order" , { amountSats : pn ( this . props . data . bond _satoshis ) } ) }
< / b > { " " + t h i s . s t e p X o f Y ( ) }
2022-01-08 13:08:03 +00:00
< / T y p o g r a p h y >
2022-04-15 16:22:49 +00:00
:
2022-01-10 18:47:16 +00:00
< Typography color = "primary" component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b >
{ t ( "Lock {{amountSats}} Sats to TAKE order" , { amountSats : pn ( this . props . data . bond _satoshis ) } ) }
< / b > { " " + t h i s . s t e p X o f Y ( ) }
2022-01-08 13:08:03 +00:00
< / T y p o g r a p h y >
}
< / G r i d >
< Grid item xs = { 12 } align = "center" >
2022-03-24 22:18:01 +00:00
< Box sx = { { bgcolor : '#ffffff' , width : '315px' , position : 'relative' , left : '-5px' } } >
< QRCode value = { this . props . data . bond _invoice } size = { 305 } style = { { position : 'relative' , top : '3px' } } / >
< / B o x >
2022-04-05 14:25:53 +00:00
< Tooltip disableHoverListener enterTouchDelay = "0" title = { t ( "Copied!" ) } >
< Button size = "small" color = "inherit" onClick = { ( ) => { navigator . clipboard . writeText ( this . props . data . bond _invoice ) } } align = "center" > < ContentCopy / > { t ( "Copy to clipboard" ) } < / B u t t o n >
2022-03-11 14:33:07 +00:00
< / T o o l t i p >
2022-04-15 16:22:49 +00:00
< / G r i d >
2022-01-08 13:08:03 +00:00
< Grid item xs = { 12 } align = "center" >
2022-04-15 16:22:49 +00:00
< TextField
2022-01-08 13:08:03 +00:00
hiddenLabel
2022-04-15 16:22:49 +00:00
variant = "standard"
2022-01-08 13:08:03 +00:00
size = "small"
2022-04-15 16:22:49 +00:00
defaultValue = { this . props . data . bond _invoice }
2022-01-08 13:08:03 +00:00
disabled = "true"
2022-04-05 14:25:53 +00:00
helperText = { t ( "This is a hold invoice, it will freeze in your wallet. It will be charged only if you cancel or lose a dispute." ) }
2022-01-08 13:08:03 +00:00
color = "secondary"
/ >
< / G r i d >
< / G r i d >
) ;
}
2022-01-09 20:05:19 +00:00
2022-01-12 12:57:03 +00:00
showBondIsLocked = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props
2022-01-12 12:57:03 +00:00
return (
< Grid item xs = { 12 } align = "center" >
2022-01-14 14:19:25 +00:00
< Typography color = "primary" component = "subtitle1" variant = "subtitle1" align = "center" >
2022-03-11 14:33:07 +00:00
< div style = { { display : 'flex' , alignItems : 'center' , justifyContent : 'center' , flexWrap : 'wrap' } } >
< LockIcon / >
2022-04-05 14:25:53 +00:00
{ this . props . data . is _maker ? t ( "Your maker bond is locked" ) : t ( "Your taker bond is locked" ) }
2022-03-11 14:33:07 +00:00
< / d i v >
2022-01-14 14:19:25 +00:00
< / T y p o g r a p h y >
2022-01-12 12:57:03 +00:00
< / G r i d >
) ;
}
2022-02-24 20:47:46 +00:00
showBondIsSettled = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-02-24 20:47:46 +00:00
return (
< Grid item xs = { 12 } align = "center" >
< Typography color = "error" component = "subtitle1" variant = "subtitle1" align = "center" >
2022-03-11 14:33:07 +00:00
< div style = { { display : 'flex' , alignItems : 'center' , justifyContent : 'center' , flexWrap : 'wrap' , align : "center" } } align = "center" >
< BalanceIcon / >
2022-04-05 14:25:53 +00:00
{ this . props . data . is _maker ? t ( "Your maker bond was settled" ) : t ( "Your taker bond was settled" ) }
2022-03-11 14:33:07 +00:00
< / d i v >
2022-02-24 20:47:46 +00:00
< / T y p o g r a p h y >
< / G r i d >
) ;
}
showBondIsReturned = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-02-24 20:47:46 +00:00
return (
< Grid item xs = { 12 } align = "center" >
< Typography color = "green" component = "subtitle1" variant = "subtitle1" align = "center" >
2022-03-11 14:33:07 +00:00
< div style = { { display : 'flex' , alignItems : 'center' , justifyContent : 'center' , flexWrap : 'wrap' } } >
< LockOpenIcon / >
2022-04-15 23:26:39 +00:00
{ this . props . data . is _maker ? t ( "Your maker bond was unlocked" ) : t ( "Your taker bond was unlocked" ) }
2022-03-11 14:33:07 +00:00
< / d i v >
2022-02-24 20:47:46 +00:00
< / T y p o g r a p h y >
< / G r i d >
) ;
}
2022-01-09 12:14:11 +00:00
showEscrowQRInvoice = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-08 17:19:30 +00:00
return (
< Grid container spacing = { 1 } >
2022-01-23 12:30:41 +00:00
{ /* Make confirmation sound for HTLC received. */ }
< this . Sound soundFileName = "locked-invoice" / >
2022-01-08 17:19:30 +00:00
< Grid item xs = { 12 } align = "center" >
2022-01-18 15:23:57 +00:00
< Typography color = "green" component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b >
{ t ( "Lock {{amountSats}} Sats as collateral" , { amountSats : pn ( this . props . data . escrow _satoshis ) } ) }
< / b > { " " + t h i s . s t e p X o f Y ( ) }
2022-01-08 17:19:30 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "center" >
2022-03-24 22:18:01 +00:00
< Box sx = { { bgcolor : '#ffffff' , width : '315px' , position : 'relative' , left : '-5px' } } >
< QRCode value = { this . props . data . escrow _invoice } size = { 305 } style = { { position : 'relative' , top : '3px' } } / >
< / B o x >
2022-04-05 14:25:53 +00:00
< Tooltip disableHoverListener enterTouchDelay = "0" title = { t ( "Copied!" ) } >
2022-04-15 23:26:39 +00:00
< Button size = "small" color = "inherit" onClick = { ( ) => { navigator . clipboard . writeText ( this . props . data . escrow _invoice ) } } align = "center" > < ContentCopy / > { t ( "Copy to clipboard" ) } < / B u t t o n >
2022-03-11 14:33:07 +00:00
< / T o o l t i p >
2022-04-15 16:22:49 +00:00
< / G r i d >
2022-01-08 17:19:30 +00:00
< Grid item xs = { 12 } align = "center" >
2022-04-15 16:22:49 +00:00
< TextField
2022-01-08 17:19:30 +00:00
hiddenLabel
2022-04-15 16:22:49 +00:00
variant = "filled"
2022-01-08 17:19:30 +00:00
size = "small"
2022-04-15 16:22:49 +00:00
defaultValue = { this . props . data . escrow _invoice }
2022-01-08 17:19:30 +00:00
disabled = "true"
2022-04-05 14:25:53 +00:00
helperText = { t ( "This is a hold invoice, it will freeze in your wallet. It will be released to the buyer once you confirm to have received the {{currencyCode}}." , { currencyCode : this . props . data . currencyCode } ) }
2022-01-08 17:19:30 +00:00
color = "secondary"
/ >
< / G r i d >
2022-01-12 12:57:03 +00:00
{ this . showBondIsLocked ( ) }
2022-01-08 17:19:30 +00:00
< / G r i d >
) ;
}
2022-01-09 01:23:13 +00:00
showTakerFound = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-09 01:23:13 +00:00
return (
< Grid container spacing = { 1 } >
2022-01-23 12:30:41 +00:00
{ /* Make bell sound when taker is found */ }
< this . Sound soundFileName = "taker-found" / >
2022-01-09 01:23:13 +00:00
< Grid item xs = { 12 } align = "center" >
< Typography component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b > { t ( "A taker has been found!" ) } < / b > { " " + t h i s . s t e p X o f Y ( ) }
2022-01-09 01:23:13 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Divider / >
< Grid item xs = { 12 } align = "center" >
2022-01-09 15:28:12 +00:00
< Typography component = "body2" variant = "body2" >
2022-04-05 14:25:53 +00:00
{ t ( "Please wait for the taker to lock a bond. If the taker does not lock a bond in time, the order will be made public again." ) }
2022-01-09 01:23:13 +00:00
< / T y p o g r a p h y >
< / G r i d >
2022-01-12 12:57:03 +00:00
{ this . showBondIsLocked ( ) }
2022-01-09 01:23:13 +00:00
< / G r i d >
) ;
}
2022-02-22 10:34:48 +00:00
handleClickOpenTelegramDialog = ( ) => {
this . setState ( { openEnableTelegram : true } ) ;
} ;
handleClickCloseEnableTelegramDialog = ( ) => {
this . setState ( { openEnableTelegram : false } ) ;
} ;
handleClickEnableTelegram = ( ) => {
window . open ( "https://t.me/" + this . props . data . tg _bot _name + '?start=' + this . props . data . tg _token , '_blank' ) . focus ( )
this . handleClickCloseEnableTelegramDialog ( ) ;
} ;
EnableTelegramDialog = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-02-22 10:34:48 +00:00
return (
< Dialog
open = { this . state . openEnableTelegram }
onClose = { this . handleClickCloseEnableTelegramDialog }
aria - labelledby = "enable-telegram-dialog-title"
aria - describedby = "enable-telegram-dialog-description"
>
< DialogTitle id = "open-dispute-dialog-title" >
2022-04-05 14:25:53 +00:00
{ t ( "Enable TG Notifications" ) }
2022-02-22 10:34:48 +00:00
< / D i a l o g T i t l e >
< DialogContent >
< DialogContentText id = "alert-dialog-description" >
2022-04-05 14:25:53 +00:00
{ t ( "You will be taken to a conversation with RoboSats telegram bot. Simply open the chat and press Start. Note that by enabling telegram notifications you might lower your level of anonymity." ) }
2022-02-22 10:34:48 +00:00
< / D i a l o g C o n t e n t T e x t >
< / D i a l o g C o n t e n t >
< DialogActions >
2022-04-05 14:25:53 +00:00
< Button onClick = { this . handleClickCloseEnableTelegramDialog } > { t ( "Go back" ) } < / B u t t o n >
< Button onClick = { this . handleClickEnableTelegram } autoFocus > { t ( "Enable" ) } < / B u t t o n >
2022-02-22 10:34:48 +00:00
< / D i a l o g A c t i o n s >
< / D i a l o g >
)
}
2022-01-08 15:34:09 +00:00
showMakerWait = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-08 15:34:09 +00:00
return (
< Grid container spacing = { 1 } >
2022-01-23 12:30:41 +00:00
{ /* Make confirmation sound for HTLC received. */ }
< this . Sound soundFileName = "locked-invoice" / >
2022-02-22 10:34:48 +00:00
< this . EnableTelegramDialog / >
2022-01-08 15:34:09 +00:00
< Grid item xs = { 12 } align = "center" >
< Typography component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b > { t ( "Your order is public" ) } < / b > { " " + t h i s . s t e p X o f Y ( ) }
2022-01-08 15:34:09 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "center" >
< List dense = "true" >
< Divider / >
< ListItem >
< Typography component = "body2" variant = "body2" align = "left" >
2022-04-15 23:26:39 +00:00
< p > { t ( "Be patient while robots check the book. This box will ring 🔊 once a robot takes your order, then you will have {{invoice_escrow_duration}} hours to reply. If you do not reply, you risk losing your bond." , { invoice _escrow _duration : pn ( this . invoice _escrow _duration ) } ) } < / p >
2022-04-16 18:34:30 +00:00
< p > { t ( "If the order expires untaken, your bond will return to you (no action needed)." ) } < / p >
2022-01-08 15:34:09 +00:00
< / T y p o g r a p h y >
< / L i s t I t e m >
2022-02-22 00:50:25 +00:00
< Grid item xs = { 12 } align = "center" >
{ this . props . data . tg _enabled ?
2022-04-05 14:25:53 +00:00
< Typography color = 'primary' component = "h6" variant = "h6" align = "center" > { t ( "Telegram enabled" ) } < / T y p o g r a p h y >
2022-02-22 00:50:25 +00:00
:
2022-02-22 10:34:48 +00:00
< Button color = "primary" onClick = { this . handleClickOpenTelegramDialog } >
2022-04-05 14:25:53 +00:00
< SendIcon / > { t ( "Enable Telegram Notifications" ) }
2022-02-22 00:50:25 +00:00
< / B u t t o n >
}
< / G r i d >
2022-01-08 15:34:09 +00:00
< Divider / >
< ListItem >
2022-01-14 13:31:54 +00:00
< ListItemIcon >
< BookIcon / >
< / L i s t I t e m I c o n >
2022-04-05 14:25:53 +00:00
< ListItemText primary = { this . props . data . num _similar _orders } secondary = { t ( "Public orders for {{currencyCode}}" , { currencyCode : this . props . data . currencyCode } ) } / >
2022-01-08 15:34:09 +00:00
< / L i s t I t e m >
2022-04-15 16:22:49 +00:00
2022-01-08 15:34:09 +00:00
< Divider / >
< ListItem >
2022-01-14 13:31:54 +00:00
< ListItemIcon >
< PercentIcon / >
< / L i s t I t e m I c o n >
2022-04-24 11:20:05 +00:00
< ListItemText primary = { t ( "Premium rank" ) + " " + Number ( this . props . data . premium _percentile * 100 ) . toPrecision ( 2 ) + "%" }
2022-04-05 14:25:53 +00:00
secondary = { t ( "Among public {{currencyCode}} orders (higher is cheaper)" , { currencyCode : this . props . data . currencyCode } ) } / >
2022-01-08 15:34:09 +00:00
< / L i s t I t e m >
2022-01-12 12:57:03 +00:00
< Divider / >
2022-01-08 15:34:09 +00:00
< / L i s t >
< / G r i d >
2022-01-12 12:57:03 +00:00
{ this . showBondIsLocked ( ) }
2022-01-08 15:34:09 +00:00
< / G r i d >
)
}
2022-01-08 13:08:03 +00:00
2022-01-09 14:07:05 +00:00
handleInputInvoiceChanged = ( e ) => {
this . setState ( {
2022-01-11 01:02:06 +00:00
invoice : e . target . value ,
2022-04-15 16:22:49 +00:00
badInvoice : false ,
2022-01-09 14:07:05 +00:00
} ) ;
}
2022-01-09 12:14:11 +00:00
2022-01-09 14:07:05 +00:00
handleClickSubmitInvoiceButton = ( ) => {
2022-01-11 01:02:06 +00:00
this . setState ( { badInvoice : false } ) ;
2022-01-09 14:07:05 +00:00
const requestOptions = {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' , 'X-CSRFToken' : getCookie ( 'csrftoken' ) , } ,
body : JSON . stringify ( {
'action' : 'update_invoice' ,
'invoice' : this . state . invoice ,
} ) ,
} ;
fetch ( '/api/order/' + '?order_id=' + this . props . data . id , requestOptions )
. then ( ( response ) => response . json ( ) )
2022-01-11 01:02:06 +00:00
. then ( ( data ) => this . setState ( { badInvoice : data . bad _invoice } )
2022-01-22 23:05:03 +00:00
& this . props . completeSetState ( data ) ) ;
2022-01-09 14:07:05 +00:00
}
2022-01-09 12:14:11 +00:00
2022-01-16 21:54:42 +00:00
handleInputDisputeChanged = ( e ) => {
this . setState ( {
statement : e . target . value ,
2022-04-15 16:22:49 +00:00
badStatement : false ,
2022-01-16 21:54:42 +00:00
} ) ;
}
handleClickSubmitStatementButton = ( ) => {
this . setState ( { badInvoice : false } ) ;
const requestOptions = {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' , 'X-CSRFToken' : getCookie ( 'csrftoken' ) , } ,
body : JSON . stringify ( {
'action' : 'submit_statement' ,
'statement' : this . state . statement ,
} ) ,
} ;
fetch ( '/api/order/' + '?order_id=' + this . props . data . id , requestOptions )
. then ( ( response ) => response . json ( ) )
. then ( ( data ) => this . setState ( { badStatement : data . bad _statement } )
2022-01-22 23:05:03 +00:00
& this . props . completeSetState ( data ) ) ;
2022-01-28 00:17:20 +00:00
}
handleScan = data => {
if ( data ) {
this . setState ( {
invoice : data
} )
}
}
handleError = err => {
console . error ( err )
}
handleQRbutton = ( ) => {
this . setState ( { qrscanner : ! this . state . qrscanner } ) ;
}
2022-01-16 21:54:42 +00:00
2022-01-09 14:07:05 +00:00
showInputInvoice ( ) {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-09 14:07:05 +00:00
return (
2022-01-09 12:14:11 +00:00
2022-01-09 14:07:05 +00:00
< Grid container spacing = { 1 } >
< Grid item xs = { 12 } align = "center" >
2022-02-03 21:51:42 +00:00
{ /* Make confirmation sound for HTLC received. */ }
< this . Sound soundFileName = "locked-invoice" / >
2022-01-10 18:47:16 +00:00
< Typography color = "primary" component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b > { t ( "Submit an invoice for {{amountSats}} Sats" , { amountSats : pn ( this . props . data . invoice _amount ) } ) }
< / b > { " " + t h i s . s t e p X o f Y ( ) }
2022-01-09 14:07:05 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "left" >
< Typography component = "body2" variant = "body2" >
2022-04-15 16:22:49 +00:00
{ t ( "The taker is committed! Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC. Please provide a valid invoice for {{amountSats}} Satoshis." ,
{ amountFiat : parseFloat ( parseFloat ( this . props . data . amount ) . toFixed ( 4 ) ) ,
currencyCode : this . props . data . currencyCode ,
amountSats : pn ( this . props . data . invoice _amount ) }
2022-04-05 14:25:53 +00:00
)
}
2022-01-09 14:07:05 +00:00
< / T y p o g r a p h y >
< / G r i d >
2022-01-15 12:00:11 +00:00
< Grid item xs = { 12 } align = "center" >
2022-04-15 16:22:49 +00:00
< TextField
2022-01-15 12:00:11 +00:00
error = { this . state . badInvoice }
helperText = { this . state . badInvoice ? this . state . badInvoice : "" }
2022-04-05 14:25:53 +00:00
label = { t ( "Payout Lightning Invoice" ) }
2022-01-15 12:00:11 +00:00
required
2022-01-28 00:17:20 +00:00
value = { this . state . invoice }
2022-01-15 12:00:11 +00:00
inputProps = { {
2022-01-27 22:51:57 +00:00
style : { textAlign : "center" } ,
maxHeight : 200 ,
2022-01-15 12:00:11 +00:00
} }
multiline
2022-01-28 00:17:20 +00:00
minRows = { 5 }
maxRows = { this . state . qrscanner ? 5 : 14 }
2022-01-15 12:00:11 +00:00
onChange = { this . handleInputInvoiceChanged }
/ >
< / G r i d >
2022-01-28 00:17:20 +00:00
{ this . state . qrscanner ?
< Grid item xs = { 12 } align = "center" >
< QrReader
delay = { 300 }
onError = { this . handleError }
onScan = { this . handleScan }
style = { { width : '75%' } }
/ >
< / G r i d >
: null }
2022-01-15 12:00:11 +00:00
< Grid item xs = { 12 } align = "center" >
2022-01-28 00:17:20 +00:00
< IconButton > < QrCodeScannerIcon onClick = { this . handleQRbutton } / > < / I c o n B u t t o n >
2022-04-15 23:26:39 +00:00
< Button onClick = { this . handleClickSubmitInvoiceButton } variant = 'contained' color = 'primary' > { t ( "Submit" ) } < / B u t t o n >
2022-01-16 21:54:42 +00:00
< / G r i d >
{ this . showBondIsLocked ( ) }
< / G r i d >
)
}
// Asks the user for a dispute statement.
2022-01-22 23:05:03 +00:00
showInDisputeStatement = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-22 23:05:03 +00:00
if ( this . props . data . statement _submitted ) {
return (
< Grid container spacing = { 1 } >
< Grid item xs = { 12 } align = "center" >
< Typography color = "primary" component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b > { t ( "We have received your statement" ) } < / b >
2022-01-22 23:05:03 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "left" >
< Typography component = "body2" variant = "body2" >
2022-04-05 14:25:53 +00:00
< p > { t ( "We are waiting for your trade counterpart statement. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com." ) } < / p >
< p > { t ( "Please, save the information needed to identify your order and your payments: order ID; payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of satoshis; and robot nickname. You will have to identify yourself as the user involved in this trade via email (or other contact methods)." ) } < / p >
2022-01-22 23:05:03 +00:00
< / T y p o g r a p h y >
< / G r i d >
2022-02-24 20:47:46 +00:00
{ this . showBondIsSettled ( ) }
2022-01-22 23:05:03 +00:00
< / G r i d >
)
} else {
return (
2022-04-15 16:22:49 +00:00
2022-01-22 23:05:03 +00:00
// TODO Option to upload files
2022-04-15 16:22:49 +00:00
2022-01-22 23:05:03 +00:00
< Grid container spacing = { 1 } >
< Grid item xs = { 12 } align = "center" >
< Typography color = "primary" component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b > { t ( "A dispute has been opened" ) } < / b >
2022-01-22 23:05:03 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "left" >
< Typography component = "body2" variant = "body2" >
2022-04-05 14:25:53 +00:00
{ t ( "Please, submit your statement. Be clear and specific about what happened and provide the necessary evidence. You MUST provide a contact method: burner email, XMPP or telegram username to follow up with the staff. Disputes are solved at the discretion of real robots (aka humans), so be as helpful as possible to ensure a fair outcome. Max 5000 chars." ) }
2022-01-22 23:05:03 +00:00
< / T y p o g r a p h y >
< / G r i d >
2022-04-15 16:22:49 +00:00
2022-01-22 23:05:03 +00:00
< Grid item xs = { 12 } align = "center" >
2022-04-15 16:22:49 +00:00
< TextField
2022-01-22 23:05:03 +00:00
error = { this . state . badStatement }
helperText = { this . state . badStatement ? this . state . badStatement : "" }
2022-04-05 14:25:53 +00:00
label = { t ( "Submit dispute statement" ) }
2022-01-22 23:05:03 +00:00
required
inputProps = { {
style : { textAlign : "center" }
} }
multiline
rows = { 4 }
onChange = { this . handleInputDisputeChanged }
/ >
< / G r i d >
< Grid item xs = { 12 } align = "center" >
< Button onClick = { this . handleClickSubmitStatementButton } variant = 'contained' color = 'primary' > Submit < / B u t t o n >
< / G r i d >
2022-02-24 20:47:46 +00:00
{ this . showBondIsSettled ( ) }
< / G r i d >
2022-01-22 23:05:03 +00:00
) }
2022-01-09 14:07:05 +00:00
}
2022-01-25 14:46:02 +00:00
showWaitForDisputeResolution = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-25 14:46:02 +00:00
return (
< Grid container spacing = { 1 } >
< Grid item xs = { 12 } align = "center" >
< Typography color = "primary" component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b > { t ( "We have the statements" ) } < / b >
2022-01-25 14:46:02 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "left" >
< Typography component = "body2" variant = "body2" >
2022-04-05 14:25:53 +00:00
< p > { t ( "Both statements have been received, wait for the staff to resolve the dispute. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com. If you did not provide a contact method, or are unsure whether you wrote it right, write us immediately." ) } < / p >
< p > { t ( "Please, save the information needed to identify your order and your payments: order ID; payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of satoshis; and robot nickname. You will have to identify yourself as the user involved in this trade via email (or other contact methods)." ) } < / p >
2022-01-25 14:46:02 +00:00
< / T y p o g r a p h y >
< / G r i d >
2022-02-24 20:47:46 +00:00
{ this . showBondIsSettled ( ) }
< / G r i d >
)
}
showDisputeWinner = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-02-24 20:47:46 +00:00
return (
< Grid container spacing = { 1 } >
< Grid item xs = { 12 } align = "center" >
< Typography color = "primary" component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b > { t ( "You have won the dispute" ) } < / b >
2022-02-24 20:47:46 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "left" >
< Typography component = "body2" variant = "body2" >
2022-04-05 14:25:53 +00:00
{ t ( "You can claim the dispute resolution amount (escrow and fidelity bond) from your profile rewards. If there is anything the staff can help with, do not hesitate to contact to robosats@protonmail.com (or via your provided burner contact method)." ) }
2022-02-24 20:47:46 +00:00
< / T y p o g r a p h y >
< / G r i d >
{ this . showBondIsSettled ( ) }
< / G r i d >
)
}
showDisputeLoser = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-02-24 20:47:46 +00:00
return (
< Grid container spacing = { 1 } >
< Grid item xs = { 12 } align = "center" >
< Typography color = "error" component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b > { t ( "You have lost the dispute" ) } < / b >
2022-02-24 20:47:46 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "left" >
< Typography component = "body2" variant = "body2" >
2022-04-05 14:25:53 +00:00
{ t ( "Unfortunately you have lost the dispute. If you think this is a mistake you can ask to re-open the case via email to robosats@protonmail.com. However, chances of it being investigated again are low." ) }
2022-02-24 20:47:46 +00:00
< / T y p o g r a p h y >
< / G r i d >
{ this . showBondIsSettled ( ) }
2022-01-25 14:46:02 +00:00
< / G r i d >
)
}
2022-01-09 14:07:05 +00:00
showWaitingForEscrow ( ) {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-09 15:28:12 +00:00
return (
< Grid container spacing = { 1 } >
< Grid item xs = { 12 } align = "center" >
< Typography component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b > { t ( "Your invoice looks good!" ) } < / b > { " " + t h i s . s t e p X o f Y ( ) }
2022-01-09 15:28:12 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "center" >
< Typography component = "body2" variant = "body2" align = "left" >
2022-04-05 14:25:53 +00:00
< p > { t ( "We are waiting for the seller lock the trade amount." ) } < / p >
< p > { t ( "Just hang on for a moment. If the seller does not deposit, you will get your bond back automatically. In addition, you will receive a compensation (check the rewards in your profile)." ) } < / p >
2022-01-09 15:28:12 +00:00
< / T y p o g r a p h y >
< / G r i d >
2022-01-12 12:57:03 +00:00
{ this . showBondIsLocked ( ) }
2022-01-09 15:28:12 +00:00
< / G r i d >
)
}
showWaitingForBuyerInvoice ( ) {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-09 15:28:12 +00:00
return (
< Grid container spacing = { 1 } >
2022-01-23 12:30:41 +00:00
{ /* Make confirmation sound for HTLC received. */ }
< this . Sound soundFileName = "locked-invoice" / >
2022-01-09 15:28:12 +00:00
< Grid item xs = { 12 } align = "center" >
< Typography component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b > { t ( "The trade collateral is locked!" ) } < / b > { " " + t h i s . s t e p X o f Y ( ) }
2022-01-09 15:28:12 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "center" >
< Typography component = "body2" variant = "body2" align = "left" >
2022-04-05 14:25:53 +00:00
< p > { t ( "We are waiting for the buyer to post a lightning invoice. Once he does, you will be able to directly communicate the fiat payment details." ) } < / p >
< p > { t ( "Just hang on for a moment. If the buyer does not cooperate, you will get back the trade collateral and your bond automatically. In addition, you will receive a compensation (check the rewards in your profile)." ) } < / p >
2022-01-09 15:28:12 +00:00
< / T y p o g r a p h y >
< / G r i d >
2022-01-12 12:57:03 +00:00
{ this . showBondIsLocked ( ) }
2022-01-09 15:28:12 +00:00
< / G r i d >
)
2022-01-09 14:07:05 +00:00
}
2022-01-09 12:14:11 +00:00
2022-01-09 20:05:19 +00:00
handleClickConfirmButton = ( ) => {
2022-01-09 15:28:12 +00:00
const requestOptions = {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' , 'X-CSRFToken' : getCookie ( 'csrftoken' ) , } ,
body : JSON . stringify ( {
2022-01-09 20:05:19 +00:00
'action' : "confirm" ,
2022-01-09 15:28:12 +00:00
} ) ,
} ;
fetch ( '/api/order/' + '?order_id=' + this . props . data . id , requestOptions )
. then ( ( response ) => response . json ( ) )
2022-01-22 23:05:03 +00:00
. then ( ( data ) => this . props . completeSetState ( data ) ) ;
2022-01-09 15:28:12 +00:00
}
2022-01-17 23:11:41 +00:00
2022-02-04 18:07:09 +00:00
handleRatingUserChange = ( e ) => {
2022-01-11 20:49:53 +00:00
const requestOptions = {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' , 'X-CSRFToken' : getCookie ( 'csrftoken' ) , } ,
body : JSON . stringify ( {
2022-02-04 18:07:09 +00:00
'action' : "rate_user" ,
'rating' : e . target . value ,
} ) ,
} ;
fetch ( '/api/order/' + '?order_id=' + this . props . data . id , requestOptions )
. then ( ( response ) => response . json ( ) )
. then ( ( data ) => this . props . completeSetState ( data ) ) ;
}
handleRatingRobosatsChange = ( e ) => {
if ( this . state . rating _platform != null ) {
return null
}
this . setState ( { rating _platform : e . target . value } ) ;
const requestOptions = {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' , 'X-CSRFToken' : getCookie ( 'csrftoken' ) , } ,
body : JSON . stringify ( {
'action' : "rate_platform" ,
2022-01-11 20:49:53 +00:00
'rating' : e . target . value ,
} ) ,
} ;
fetch ( '/api/order/' + '?order_id=' + this . props . data . id , requestOptions )
. then ( ( response ) => response . json ( ) )
2022-01-22 23:05:03 +00:00
. then ( ( data ) => this . props . completeSetState ( data ) ) ;
2022-01-11 20:49:53 +00:00
}
2022-01-09 12:14:11 +00:00
2022-01-09 15:28:12 +00:00
showFiatSentButton ( ) {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-09 15:28:12 +00:00
return (
< Grid container spacing = { 1 } >
< Grid item xs = { 12 } align = "center" >
2022-04-05 14:25:53 +00:00
< Button defaultValue = "confirm" variant = 'contained' color = 'secondary' onClick = { this . handleClickConfirmButton } > { t ( "Confirm {{currencyCode}} sent" , { currencyCode : this . props . data . currencyCode } ) } < / B u t t o n >
2022-01-09 20:05:19 +00:00
< / G r i d >
< / G r i d >
)
}
showFiatReceivedButton ( ) {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-09 20:05:19 +00:00
return (
< Grid item xs = { 12 } align = "center" >
2022-04-05 14:25:53 +00:00
< Button defaultValue = "confirm" variant = 'contained' color = 'secondary' onClick = { this . handleClickOpenConfirmFiatReceived } > { t ( "Confirm {{currencyCode}} received" , { currencyCode : this . props . data . currencyCode } ) } < / B u t t o n >
2022-01-09 20:05:19 +00:00
< / G r i d >
)
}
showOpenDisputeButton ( ) {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-09 20:05:19 +00:00
return (
< Grid item xs = { 12 } align = "center" >
2022-04-05 14:25:53 +00:00
< Button color = "inherit" onClick = { this . handleClickOpenConfirmDispute } > { t ( "Open Dispute" ) } < / B u t t o n >
2022-01-09 20:05:19 +00:00
< / G r i d >
)
}
2022-01-18 15:45:04 +00:00
showOrderExpired ( ) {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-18 15:45:04 +00:00
return (
< Grid container spacing = { 1 } >
< Grid item xs = { 12 } align = "center" >
< Typography component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b > { t ( "The order has expired" ) } < / b >
2022-01-18 15:45:04 +00:00
< / T y p o g r a p h y >
< / G r i d >
< / G r i d >
)
}
2022-01-19 22:44:31 +00:00
showChat = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-19 22:44:31 +00:00
//In Chatroom - No fiat sent - showChat(showSendButton, showReveiceButton, showDisputeButton)
2022-01-22 23:05:03 +00:00
if ( this . props . data . is _buyer & this . props . data . status == 9 ) {
2022-01-19 22:44:31 +00:00
var showSendButton = true ;
var showReveiceButton = false ;
var showDisputeButton = true ;
}
2022-01-22 23:05:03 +00:00
if ( this . props . data . is _seller & this . props . data . status == 9 ) {
2022-01-19 22:44:31 +00:00
var showSendButton = false ;
var showReveiceButton = false ;
var showDisputeButton = true ;
}
2022-04-15 16:22:49 +00:00
2022-01-19 22:44:31 +00:00
//In Chatroom - Fiat sent - showChat(showSendButton, showReveiceButton, showDisputeButton)
2022-01-22 23:05:03 +00:00
if ( this . props . data . is _buyer & this . props . data . status == 10 ) {
2022-01-19 22:44:31 +00:00
var showSendButton = false ;
var showReveiceButton = false ;
var showDisputeButton = true ;
}
2022-01-22 23:05:03 +00:00
if ( this . props . data . is _seller & this . props . data . status == 10 ) {
2022-01-19 22:44:31 +00:00
var showSendButton = false ;
var showReveiceButton = true ;
var showDisputeButton = true ;
2022-04-15 16:22:49 +00:00
}
2022-01-09 20:05:19 +00:00
return (
< Grid container spacing = { 1 } >
2022-01-23 12:30:41 +00:00
{ /* Make confirmation sound for Chat Open. */ }
< this . Sound soundFileName = "chat-open" / >
2022-01-09 20:05:19 +00:00
< Grid item xs = { 12 } align = "center" >
< Typography component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b > { this . props . data . is _seller ? t ( "Chat with the buyer" ) : t ( "Chat with the seller" ) } < / b > { " " + t h i s . s t e p X o f Y ( ) }
2022-01-09 20:05:19 +00:00
< / T y p o g r a p h y >
< / G r i d >
2022-01-13 20:41:48 +00:00
< Grid item xs = { 12 } align = "center" >
2022-04-15 16:22:49 +00:00
{ this . props . data . is _seller ?
2022-01-13 20:41:48 +00:00
< Typography component = "body2" variant = "body2" align = "center" >
2022-03-11 14:33:07 +00:00
{ this . props . data . status == 9 ?
2022-04-05 14:25:53 +00:00
t ( "Say hi! Be helpful and concise. Let them know how to send you {{currencyCode}}." , { currencyCode : this . props . data . currencyCode } )
2022-03-11 14:33:07 +00:00
:
2022-04-05 14:25:53 +00:00
t ( "The buyer has sent the fiat. Click 'Confirm Received' once you receive it." )
2022-03-11 14:33:07 +00:00
}
2022-01-09 20:05:19 +00:00
< / T y p o g r a p h y >
:
2022-01-13 20:41:48 +00:00
< Typography component = "body2" variant = "body2" align = "center" >
2022-03-11 14:33:07 +00:00
{ this . props . data . status == 9 ?
2022-04-05 14:25:53 +00:00
t ( "Say hi! Ask for payment details and click 'Confirm Sent' as soon as the payment is sent." )
2022-03-11 14:33:07 +00:00
:
2022-04-05 14:25:53 +00:00
t ( "Wait for the seller to confirm he has received the payment." )
2022-03-11 14:33:07 +00:00
}
2022-01-09 20:05:19 +00:00
< / T y p o g r a p h y >
}
< / G r i d >
2022-01-13 19:22:54 +00:00
2022-01-22 23:05:03 +00:00
< Chat orderId = { this . props . data . id } ur _nick = { this . props . data . ur _nick } / >
2022-01-09 20:05:19 +00:00
< Grid item xs = { 12 } align = "center" >
2022-01-19 22:44:31 +00:00
{ showDisputeButton ? this . showOpenDisputeButton ( ) : "" }
{ showSendButton ? this . showFiatSentButton ( ) : "" }
{ showReveiceButton ? this . showFiatReceivedButton ( ) : "" }
2022-01-09 15:28:12 +00:00
< / G r i d >
2022-01-12 12:57:03 +00:00
{ this . showBondIsLocked ( ) }
2022-01-09 15:28:12 +00:00
< / G r i d >
)
}
2022-01-11 20:49:53 +00:00
showRateSelect ( ) {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-11 20:49:53 +00:00
return (
< Grid container spacing = { 1 } >
2022-01-23 12:30:41 +00:00
{ /* Make confirmation sound for Chat Open. */ }
< this . Sound soundFileName = "successful" / >
2022-01-11 20:49:53 +00:00
< Grid item xs = { 12 } align = "center" >
< Typography component = "h6" variant = "h6" >
2022-04-05 14:25:53 +00:00
{ t ( "🎉Trade finished!🥳" ) }
2022-01-11 20:49:53 +00:00
< / T y p o g r a p h y >
< / G r i d >
2022-03-06 16:08:28 +00:00
{ / * < G r i d i t e m x s = { 1 2 } a l i g n = " c e n t e r " >
2022-01-11 20:49:53 +00:00
< Typography component = "body2" variant = "body2" align = "center" >
2022-02-04 18:07:09 +00:00
What do you think of ⚡ < b > { this . props . data . is _maker ? this . props . data . taker _nick : this . props . data . maker _nick } < / b > ⚡ ?
2022-01-11 20:49:53 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "center" >
2022-02-04 18:07:09 +00:00
< Rating name = "size-large" defaultValue = { 0 } size = "large" onChange = { this . handleRatingUserChange } / >
2022-03-06 16:08:28 +00:00
< /Grid> */ }
2022-02-04 18:07:09 +00:00
< Grid item xs = { 12 } align = "center" >
< Typography component = "body2" variant = "body2" align = "center" >
2022-04-05 14:25:53 +00:00
< Trans i18nKey = "rate_robosats" > What do you think of 🤖 < b > RoboSats < / b > ⚡ ? < / T r a n s >
2022-02-04 18:07:09 +00:00
< / T y p o g r a p h y >
2022-01-11 20:49:53 +00:00
< / G r i d >
2022-02-04 18:07:09 +00:00
< Grid item xs = { 12 } align = "center" >
< Rating name = "size-large" defaultValue = { 0 } size = "large" onChange = { this . handleRatingRobosatsChange } / >
< / G r i d >
{ this . state . rating _platform == 5 ?
< Grid item xs = { 12 } align = "center" >
< Typography component = "body2" variant = "body2" align = "center" >
2022-04-05 14:25:53 +00:00
< p > < b > { t ( "Thank you! RoboSats loves you too ❤️" ) } < / b > < / p >
< p > { t ( "RoboSats gets better with more liquidity and users. Tell a bitcoiner friend about Robosats!" ) } < / p >
2022-02-04 18:07:09 +00:00
< / T y p o g r a p h y >
< / G r i d >
: null }
{ this . state . rating _platform != 5 & this . state . rating _platform != null ?
< Grid item xs = { 12 } align = "center" >
< Typography component = "body2" variant = "body2" align = "center" >
2022-04-15 16:22:49 +00:00
< p > < b > { t ( "Thank you for using Robosats!" ) } < / b > < / p >
2022-04-05 14:25:53 +00:00
< p > < Trans i18nKey = "let_us_know_hot_to_improve" > Let us know how the platform could improve ( < Link target = '_blank' href = "https://t.me/robosats" > Telegram < /Link> / < Link target = '_blank' href = "https://github.com/Reckless-Satoshi/robosats/issues" > Github < / L i n k > ) < / T r a n s > < / p >
2022-02-04 18:07:09 +00:00
< / T y p o g r a p h y >
< / G r i d >
: null }
2022-01-11 20:49:53 +00:00
< Grid item xs = { 12 } align = "center" >
2022-04-15 16:22:49 +00:00
< Button color = 'primary' onClick = { ( ) => { this . props . push ( '/' ) } } > { t ( "Start Again" ) } < / B u t t o n >
2022-01-11 20:49:53 +00:00
< / G r i d >
2022-02-24 20:47:46 +00:00
{ this . showBondIsReturned ( ) }
< / G r i d >
2022-01-11 20:49:53 +00:00
)
}
2022-01-09 12:14:11 +00:00
2022-01-23 21:56:26 +00:00
showSendingPayment ( ) {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-23 21:56:26 +00:00
return (
< Grid container spacing = { 1 } >
< Grid item xs = { 12 } align = "center" >
< Typography component = "h6" variant = "h6" >
2022-04-05 14:25:53 +00:00
{ t ( "Attempting Lightning Payment" ) }
2022-01-23 21:56:26 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "center" >
< Typography component = "body2" variant = "body2" align = "center" >
2022-04-05 14:25:53 +00:00
{ t ( "RoboSats is trying to pay your lightning invoice. Remember that lightning nodes must be online in order to receive payments." ) }
2022-01-23 21:56:26 +00:00
< / T y p o g r a p h y >
2022-02-04 18:07:09 +00:00
< br / >
< Grid item xs = { 12 } align = "center" >
< CircularProgress / >
< / G r i d >
2022-01-23 21:56:26 +00:00
< / G r i d >
< / G r i d >
)
}
2022-04-15 16:22:49 +00:00
// Countdown Renderer callback with condition
2022-02-04 18:07:09 +00:00
countdownRenderer = ( { minutes , seconds , completed } ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-02-04 18:07:09 +00:00
if ( completed ) {
// Render a completed state
2022-04-05 14:25:53 +00:00
return ( < div align = "center" > < span > { t ( "Retrying!" ) } < /span><br/ > < CircularProgress / > < / d i v > ) ;
2022-04-15 16:22:49 +00:00
2022-02-04 18:07:09 +00:00
} else {
return (
< span > { zeroPad ( minutes ) } m { zeroPad ( seconds ) } s < / s p a n >
) ;
}
} ;
2022-01-24 22:53:55 +00:00
showRoutingFailed = ( ) => {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-24 22:53:55 +00:00
if ( this . props . data . invoice _expired ) {
return (
< Grid container spacing = { 1 } >
< Grid item xs = { 12 } align = "center" >
< Typography component = "h6" variant = "h6" >
2022-04-05 14:25:53 +00:00
{ t ( "Lightning Routing Failed" ) }
2022-01-24 22:53:55 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "center" >
< Typography component = "body2" variant = "body2" align = "center" >
2022-04-15 16:22:49 +00:00
{ t ( "Your invoice has expired or more than 3 payment attempts have been made. Muun wallet is not recommended. " ) }
2022-04-05 14:25:53 +00:00
< Link href = "https://github.com/Reckless-Satoshi/robosats/issues/44" > { t ( "Check the list of compatible wallets" ) } < / L i n k >
2022-01-24 22:53:55 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "center" >
< Typography color = "primary" component = "subtitle1" variant = "subtitle1" >
2022-04-05 14:25:53 +00:00
< b > { t ( "Submit an invoice for {{amountSats}} Sats" , { amountSats : pn ( this . props . data . invoice _amount ) } ) } < / b >
2022-01-24 22:53:55 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "center" >
2022-04-15 16:22:49 +00:00
< TextField
2022-01-24 22:53:55 +00:00
error = { this . state . badInvoice }
helperText = { this . state . badInvoice ? this . state . badInvoice : "" }
2022-04-05 14:25:53 +00:00
label = { t ( "Payout Lightning Invoice" ) }
2022-01-24 22:53:55 +00:00
required
inputProps = { {
style : { textAlign : "center" }
} }
multiline
2022-03-03 15:40:56 +00:00
minRows = { 4 }
maxRows = { 8 }
2022-01-24 22:53:55 +00:00
onChange = { this . handleInputInvoiceChanged }
/ >
< / G r i d >
< Grid item xs = { 12 } align = "center" >
< Button onClick = { this . handleClickSubmitInvoiceButton } variant = 'contained' color = 'primary' > Submit < / B u t t o n >
< / G r i d >
2022-02-24 20:47:46 +00:00
{ this . showBondIsReturned ( ) }
< / G r i d >
2022-01-24 22:53:55 +00:00
)
} else {
2022-01-23 21:56:26 +00:00
return (
< Grid container spacing = { 1 } >
< Grid item xs = { 12 } align = "center" >
< Typography component = "h6" variant = "h6" >
2022-04-05 14:25:53 +00:00
{ t ( "Lightning Routing Failed" ) }
2022-01-23 21:56:26 +00:00
< / T y p o g r a p h y >
< / G r i d >
< Grid item xs = { 12 } align = "center" >
< Typography component = "body2" variant = "body2" align = "center" >
2022-04-05 14:25:53 +00:00
{ t ( "RoboSats will try to pay your invoice 3 times every 5 minutes. If it keeps failing, you will be able to submit a new invoice. Check whether you have enough inbound liquidity. Remember that lightning nodes must be online in order to receive payments." ) }
2022-01-23 21:56:26 +00:00
< / T y p o g r a p h y >
< List >
2022-01-24 22:53:55 +00:00
< Divider / >
2022-04-05 14:25:53 +00:00
< ListItemText secondary = { t ( "Next attempt in" ) } >
2022-01-23 21:56:26 +00:00
< Countdown date = { new Date ( this . props . data . next _retry _time ) } renderer = { this . countdownRenderer } / >
< / L i s t I t e m T e x t >
< / L i s t >
< / G r i d >
2022-02-24 20:47:46 +00:00
{ this . showBondIsReturned ( ) }
< / G r i d >
2022-01-24 22:53:55 +00:00
) }
2022-01-23 21:56:26 +00:00
}
2022-01-08 13:08:03 +00:00
render ( ) {
2022-04-05 14:25:53 +00:00
const { t } = this . props ;
2022-01-08 13:08:03 +00:00
return (
2022-01-29 14:42:54 +00:00
< Grid container spacing = { 1 } style = { { width : this . props . width } } >
2022-01-17 23:11:41 +00:00
< this . ConfirmDisputeDialog / >
< this . ConfirmFiatReceivedDialog / >
2022-01-08 13:08:03 +00:00
< Grid item xs = { 12 } align = "center" >
2022-01-27 22:51:57 +00:00
< MediaQuery minWidth = { 920 } >
< Typography component = "h5" variant = "h5" >
2022-04-05 14:25:53 +00:00
{ t ( "Contract Box" ) }
2022-01-27 22:51:57 +00:00
< / T y p o g r a p h y >
< / M e d i a Q u e r y >
2022-01-08 13:08:03 +00:00
< Paper elevation = { 12 } style = { { padding : 8 , } } >
2022-01-09 12:14:11 +00:00
{ /* Maker and taker Bond request */ }
2022-01-22 23:05:03 +00:00
{ this . props . data . is _maker & this . props . data . status == 0 ? this . showQRInvoice ( ) : "" }
{ this . props . data . is _taker & this . props . data . status == 3 ? this . showQRInvoice ( ) : "" }
2022-01-09 12:14:11 +00:00
{ /* Waiting for taker and taker bond request */ }
2022-01-22 23:05:03 +00:00
{ this . props . data . is _maker & this . props . data . status == 1 ? this . showMakerWait ( ) : "" }
{ this . props . data . is _maker & this . props . data . status == 3 ? this . showTakerFound ( ) : "" }
2022-01-09 12:14:11 +00:00
{ /* Send Invoice (buyer) and deposit collateral (seller) */ }
2022-01-22 23:05:03 +00:00
{ this . props . data . is _seller & ( this . props . data . status == 6 || this . props . data . status == 7 ) ? this . showEscrowQRInvoice ( ) : "" }
{ this . props . data . is _buyer & ( this . props . data . status == 6 || this . props . data . status == 8 ) ? this . showInputInvoice ( ) : "" }
{ this . props . data . is _buyer & this . props . data . status == 7 ? this . showWaitingForEscrow ( ) : "" }
{ this . props . data . is _seller & this . props . data . status == 8 ? this . showWaitingForBuyerInvoice ( ) : "" }
2022-01-09 12:14:11 +00:00
2022-01-19 22:44:31 +00:00
{ /* In Chatroom */ }
2022-01-22 23:05:03 +00:00
{ this . props . data . status == 9 || this . props . data . status == 10 ? this . showChat ( ) : "" }
2022-01-09 12:14:11 +00:00
{ /* Trade Finished */ }
2022-01-23 21:56:26 +00:00
{ ( this . props . data . is _seller & [ 13 , 14 , 15 ] . includes ( this . props . data . status ) ) ? this . showRateSelect ( ) : "" }
2022-01-22 23:05:03 +00:00
{ ( this . props . data . is _buyer & this . props . data . status == 14 ) ? this . showRateSelect ( ) : "" }
2022-01-11 20:49:53 +00:00
{ /* Trade Finished - Payment Routing Failed */ }
2022-01-23 21:56:26 +00:00
{ this . props . data . is _buyer & this . props . data . status == 13 ? this . showSendingPayment ( ) : "" }
{ /* Trade Finished - Payment Routing Failed */ }
{ this . props . data . is _buyer & this . props . data . status == 15 ? this . showRoutingFailed ( ) : "" }
2022-01-11 20:49:53 +00:00
2022-01-16 21:54:42 +00:00
{ /* Trade Finished - TODO Needs more planning */ }
2022-01-22 23:05:03 +00:00
{ this . props . data . status == 11 ? this . showInDisputeStatement ( ) : "" }
2022-01-25 14:46:02 +00:00
{ this . props . data . status == 16 ? this . showWaitForDisputeResolution ( ) : "" }
2022-02-24 20:47:46 +00:00
{ ( this . props . data . status == 17 & this . props . data . is _taker ) || ( this . props . data . status == 18 & this . props . data . is _maker ) ? this . showDisputeWinner ( ) : "" }
{ ( this . props . data . status == 18 & this . props . data . is _taker ) || ( this . props . data . status == 17 & this . props . data . is _maker ) ? this . showDisputeLoser ( ) : "" }
2022-01-18 15:45:04 +00:00
{ /* Order has expired */ }
2022-01-22 23:05:03 +00:00
{ this . props . data . status == 5 ? this . showOrderExpired ( ) : "" }
2022-01-09 12:14:11 +00:00
{ /* TODO */ }
{ /* */ }
{ /* */ }
2022-01-09 12:35:19 +00:00
2022-01-08 13:08:03 +00:00
< / P a p e r >
< / G r i d >
< / G r i d >
) ;
}
2022-04-05 14:25:53 +00:00
}
2022-04-15 16:22:49 +00:00
export default withTranslation ( ) ( TradeBox ) ;