-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cad52b5
commit 2c9ea77
Showing
14 changed files
with
695 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* eslint react/prop-types: 0 */ | ||
import React from 'react'; | ||
import tt from 'counterpart' | ||
|
||
import Tooltip from 'app/components/elements/Tooltip'; | ||
|
||
const SECOND = 1000 | ||
const MINUTE = 60*SECOND | ||
const HOUR = 60*MINUTE | ||
const DAY = 24*HOUR | ||
|
||
function formatTimeExact(dt, maxDepth = 2) { | ||
const msec = +dt | ||
const now = Date.now() | ||
|
||
const formatMsec = (ms, depth = 1, prev = null) => { | ||
if (depth > maxDepth) return '' | ||
if (ms >= DAY) { | ||
const days = Math.floor(ms / DAY) | ||
const remainder = ms % DAY | ||
const res = days ? days + tt('time_exact_wrapper_jsx.days') : '' | ||
return res + formatMsec(remainder, ++depth, DAY) | ||
} else if (ms >= HOUR && (!prev || prev == DAY)) { | ||
const hours = Math.floor(ms / HOUR) | ||
const remainder = ms % HOUR | ||
const res = hours ? hours + tt('time_exact_wrapper_jsx.hours') : '' | ||
return res + formatMsec(remainder, ++depth, HOUR) | ||
} else if (ms >= MINUTE && (!prev || prev == HOUR)) { | ||
const minutes = Math.floor(ms / MINUTE) | ||
const remainder = ms % MINUTE | ||
const res = minutes ? minutes + tt('time_exact_wrapper_jsx.minutes') : '' | ||
return res + formatMsec(remainder, ++depth, MINUTE) | ||
} else if (!prev || prev == MINUTE) { | ||
const secs = Math.floor(ms / SECOND) | ||
return secs ? secs + tt('time_exact_wrapper_jsx.secs') : '' | ||
} else { | ||
return '' | ||
} | ||
} | ||
|
||
const deltaSign = now - msec | ||
const delta = Math.abs(deltaSign) | ||
|
||
const result = formatMsec(delta) | ||
return { | ||
result, | ||
ago: deltaSign > 0 | ||
} | ||
} | ||
|
||
export default class TimeExactWrapper extends React.Component { | ||
render() { | ||
let {date, className} = this.props | ||
if (date && /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d$/.test(date)) { | ||
date = date + 'Z' // Firefox really wants this Z (Zulu) | ||
} | ||
const dt = new Date(date) | ||
return <Tooltip t={dt.toLocaleString()} className={className}> | ||
{formatTimeExact(dt).result} | ||
</Tooltip> | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,248 @@ | ||
import React, { Component, } from 'react' | ||
import tt from 'counterpart' | ||
import { connect, } from 'react-redux' | ||
import CloseButton from 'react-foundation-components/lib/global/close-button' | ||
import { Formik, Form, Field, ErrorMessage, } from 'formik' | ||
import { api } from 'golos-lib-js' | ||
import { validateAccountName, Asset, AssetEditor } from 'golos-lib-js/lib/utils' | ||
|
||
import AmountField from 'app/components/elements/forms/AmountField' | ||
import AmountAssetField from 'app/components/elements/forms/AmountAssetField' | ||
import LoadingIndicator from 'app/components/elements/LoadingIndicator' | ||
import NFTSmallIcon from 'app/components/elements/nft/NFTSmallIcon' | ||
import transaction from 'app/redux/Transaction' | ||
|
||
const isDev = () => { | ||
return process.env.NODE_ENV === 'development' | ||
} | ||
|
||
class NFTAuction extends Component { | ||
state = { | ||
auction: { | ||
min_price: AssetEditor('0.000 GOLOS'), | ||
expiration: isDev() ? 15 : 7 | ||
} | ||
} | ||
|
||
async componentDidMount() { | ||
const isHidden = (sym) => { | ||
return ($STM_Config.hidden_assets && $STM_Config.hidden_assets[sym]) | ||
} | ||
try { | ||
const assets = {} | ||
const data = await api.getAssetsAsync('', [], '', 5000, 'by_symbol_name', { system: true }) | ||
for (const asset of data) { | ||
asset.supply = Asset(asset.supply) | ||
assets[asset.supply.symbol] = asset | ||
} | ||
this.setState({ | ||
assets | ||
}) | ||
} catch (err) { | ||
console.error(err) | ||
} | ||
} | ||
|
||
validate = (values) => { | ||
const errors = {} | ||
const { min_price } = values | ||
if (min_price.asset.eq(0)) { | ||
errors.min_price = tt('nft_token_sell_jsx.fill_price') | ||
} | ||
return errors | ||
} | ||
|
||
setSubmitting = (submitting) => { | ||
this.setState({ submitting }) | ||
} | ||
|
||
getToken = () => { | ||
const { nft_tokens, tokenIdx } = this.props | ||
if (tokenIdx !== undefined) { | ||
return nft_tokens.toJS().data[tokenIdx] | ||
} | ||
return this.props.token | ||
} | ||
|
||
_onSubmit = async (values) => { | ||
this.setSubmitting(true) | ||
this.setState({ | ||
errorMessage: '' | ||
}) | ||
|
||
const { currentUser, onClose, } = this.props | ||
const token = this.getToken() | ||
const { token_id } = token | ||
|
||
const username = currentUser.get('username') | ||
|
||
let expirationSec = parseInt(values.expiration) | ||
if (!isDev()) { | ||
expirationSec *= 3600*24 | ||
} | ||
let gprops | ||
try { | ||
gprops = await api.getDynamicGlobalPropertiesAsync() | ||
} catch (err) { | ||
console.error(err) | ||
alert('Error - blockchain unavailable') | ||
return | ||
} | ||
let expiration = new Date(gprops.time) | ||
expiration.setSeconds(expiration.getSeconds() + expirationSec) | ||
|
||
await this.props.auction(token_id, values.min_price.asset, expiration, username, () => { | ||
this.props.onClose() | ||
this.setSubmitting(false) | ||
this.doNotRender = true | ||
this.props.refetch() | ||
}, (err) => { | ||
console.error(err) | ||
this.setSubmitting(false) | ||
this.setState({ | ||
errorMessage: err.toString() | ||
}) | ||
}) | ||
} | ||
|
||
onCancelMouseDown = (e) => { | ||
e.preventDefault() | ||
this.setState({ | ||
cancelMouseDown: true | ||
}) | ||
} | ||
|
||
onCancelMouseUp = (e) => { | ||
e.preventDefault() | ||
if (this.state.cancelMouseDown) { | ||
this.props.onClose() | ||
this.setState({ | ||
cancelMouseDown: false | ||
}) | ||
} | ||
} | ||
|
||
onMouseUp = (e) => { | ||
/*e.preventDefault() | ||
if (this.state.cancelMouseDown) { | ||
this.props.onClose() | ||
}*/ | ||
} | ||
|
||
onAssetChange = (e, asset) => { | ||
this.setState({ | ||
currentBalance: asset.supply.clone() | ||
}) | ||
} | ||
|
||
_renderSubmittingIndicator = () => { | ||
const { submitting } = this.state | ||
|
||
return submitting ? <span className='submitter'> | ||
<LoadingIndicator type='circle' /> | ||
</span> : null | ||
} | ||
|
||
render() { | ||
const { assets } = this.state | ||
|
||
if (this.doNotRender || !assets) { | ||
return <LoadingIndicator type='circle' /> | ||
} | ||
|
||
const { onClose, } = this.props | ||
|
||
const token = this.getToken() | ||
|
||
const { json_metadata, image } = token | ||
|
||
let data | ||
if (json_metadata) { | ||
data = JSON.parse(json_metadata) | ||
} | ||
data = data || {} // node allows to use '', null, object, or array | ||
|
||
const { errorMessage, submitting, currentBalance, } = this.state | ||
|
||
return <div className='NFTAuction'> | ||
<CloseButton onClick={onClose} /> | ||
<h4>{tt('nft_tokens_jsx.start_auction')}</h4> | ||
<div style={{ marginBottom: '0.5rem' }}> | ||
<NFTSmallIcon image={image} /> | ||
<span style={{ display: 'inline-block', marginTop: '13px', marginLeft: '0.5rem' }}>{data.title}</span> | ||
</div> | ||
<Formik | ||
initialValues={this.state.auction} | ||
enableReinitialize={true} | ||
validate={this.validate} | ||
validateOnMount={true} | ||
onSubmit={this._onSubmit} | ||
> | ||
{({ | ||
handleSubmit, isValid, values, errors, touched, setFieldValue, handleChange, | ||
}) => { | ||
return ( | ||
<Form onMouseUp={this.onMouseUp}> | ||
<div> | ||
{tt('nft_tokens_jsx.min_price')} | ||
</div> | ||
<div className='row'> | ||
<div className='column small-12'> | ||
<div className='input-group' style={{marginBottom: 5}}> | ||
<AmountField name='min_price' autoFocus /> | ||
<span className="input-group-label" style={{paddingLeft: 0, paddingRight: 0}}> | ||
<AmountAssetField amountField='min_price' setFieldValue={setFieldValue} values={values} assets={assets} | ||
onChange={this.onAssetChange}/> | ||
</span> | ||
</div> | ||
{errors.min_price && <div className='error'>{errors.min_price}</div>} | ||
</div> | ||
</div> | ||
<div> | ||
{tt('nft_tokens_jsx.auction_expiration')} | ||
</div> | ||
<div className='row'> | ||
<div className='column small-12'> | ||
<div className='input-group' style={{marginBottom: 5}}> | ||
<Field type='number' name='expiration' /> | ||
<span className="input-group-label"> | ||
{isDev() ? tt('nft_tokens_jsx.auction_expiration_dev') : tt('nft_tokens_jsx.auction_expiration2')} | ||
</span> | ||
</div> | ||
{errors.expiration && <div className='error'>{errors.expiration}</div>} | ||
</div> | ||
</div> | ||
{(errorMessage && errorMessage !== 'Canceled') ? <div className='row'> | ||
<div className='column small-12'> | ||
<div className='error' style={{marginBottom:'0px'}}>{errorMessage}</div> | ||
</div> | ||
</div> : null} | ||
<div className='row' style={{ marginTop: '0.5rem' }}> | ||
<div className='column small-8'> | ||
<button type='submit' disabled={!isValid || submitting} className='button'> | ||
{tt('nft_tokens_jsx.start')} | ||
</button> | ||
<button type='button' disabled={submitting} className='button hollow' | ||
onMouseDown={this.onCancelMouseDown} onMouseUp={this.onCancelMouseUp}> | ||
{tt('g.cancel')} | ||
</button> | ||
{this._renderSubmittingIndicator()} | ||
</div> | ||
</div> | ||
</Form> | ||
)}}</Formik> | ||
</div> | ||
} | ||
} | ||
|
||
export default connect( | ||
// mapStateToProps | ||
(state, ownProps) => { | ||
return { ...ownProps, | ||
nft_tokens: state.global.get('nft_tokens'), | ||
} | ||
}, | ||
|
||
dispatch => ({ | ||
}) | ||
)(NFTAuction) |
2 changes: 1 addition & 1 deletion
2
app/components/modules/nft/NFTPlaceBet.scss → app/components/modules/nft/NFTAuction.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
.NFTPlaceBet { | ||
.NFTAuction { | ||
.column { | ||
padding-left: 0rem; | ||
padding-right: 0rem; | ||
|
Oops, something went wrong.