From 1e2005a02e64622ca451e1e54d150ace45e1c594 Mon Sep 17 00:00:00 2001 From: 1aerostorm Date: Thu, 30 May 2024 21:03:06 +0300 Subject: [PATCH] HF 30 - NFT, auction... --- app/components/elements/FitText.jsx | 57 ++++++++++++++ app/components/elements/FitTextOld.jsx | 56 ++++++++++++++ app/components/elements/TimeExactWrapper.jsx | 6 +- app/components/elements/nft/NFTTokenItem.jsx | 19 +++-- app/components/modules/nft/NFTMyOrders.jsx | 80 ++++++++++++++++---- app/components/modules/nft/NFTMyOrders.scss | 9 +++ app/components/pages/nft/NFTMarketPage.jsx | 3 +- app/components/pages/nft/NFTTokenPage.jsx | 2 +- app/redux/FetchDataSaga.js | 12 ++- 9 files changed, 214 insertions(+), 30 deletions(-) create mode 100644 app/components/elements/FitText.jsx create mode 100644 app/components/elements/FitTextOld.jsx diff --git a/app/components/elements/FitText.jsx b/app/components/elements/FitText.jsx new file mode 100644 index 0000000..57ad14f --- /dev/null +++ b/app/components/elements/FitText.jsx @@ -0,0 +1,57 @@ +import React from 'react' + +const tryIt = (text, fontSize = undefined) => { + const el = document.createElement('h5') + el.style.display = 'none' + const span = document.createElement('span') + if (fontSize) + span.style.fontSize = fontSize + el.appendChild(span) + document.body.appendChild(el) + const font1 = getComputedStyle(span).font + el.remove() + const cnv1 = document.createElement('canvas') + const ctx1 = cnv1.getContext('2d') + ctx1.font = font1 + return ctx1.measureText(text).width +} + +export default class FitText extends React.Component { + state = {} + + constructor(props) { + super(props) + } + + render() { + let { maxWidth, shrink } = this.props + let text = this.props.text + + let fontSize + let width = tryIt(text) + if (width > maxWidth) { + fontSize = '90%' + } + width = tryIt(text, fontSize) + if (width > maxWidth) { + fontSize = '85%' + } + width = tryIt(text, fontSize) + if (width > maxWidth) { + fontSize = '80%' + for (let i = 0; i < 10; ++i) { + width = tryIt(text, fontSize) + if (width > maxWidth) { + if (shrink) + text = this.props.text + text = text.substring(0, text.length - (2 * i)) + '...' + } else { + break + } + } + } + + return + {text} + } +} diff --git a/app/components/elements/FitTextOld.jsx b/app/components/elements/FitTextOld.jsx new file mode 100644 index 0000000..f61019c --- /dev/null +++ b/app/components/elements/FitTextOld.jsx @@ -0,0 +1,56 @@ +import React from 'react' + +const MAX_SCALE = 6 + +export default class FitText extends React.Component { + state = { scale: 0 } + + constructor(props) { + super(props) + this.span = React.createRef() + } + + onRender = () => { + console.timeEnd('R1') + const { current } = this.span + if (!current || this.state.scaled) return + const width = current.offsetWidth + const { maxWidth } = this.props + if (width > maxWidth) { + const { scale } = this.state + if (scale === MAX_SCALE) { + this.setState({ + scaled: true + }) + return + } + this.setState({ + scale: scale + 1 + }) + } else { + this.setState({ + scaled: true + }) + } + } + + render() { + let { text, maxWidth, shrink, shrink2 } = this.props + const { scale } = this.state + + let fontSize + if (scale === 1) { + fontSize = '90%' + } else if (scale === 2) { + fontSize = '85%' + } else if (scale >= 3) { + fontSize = '80%' + if (shrink) + text = text.substring(0, shrink - (5 * (scale - 3))) + '...' + } + + return + + {text} + } +} diff --git a/app/components/elements/TimeExactWrapper.jsx b/app/components/elements/TimeExactWrapper.jsx index fa7fb26..ddaac2b 100644 --- a/app/components/elements/TimeExactWrapper.jsx +++ b/app/components/elements/TimeExactWrapper.jsx @@ -50,7 +50,7 @@ function formatTimeExact(dt, maxDepth = 2, shorter = false) { } export default class TimeExactWrapper extends React.Component { - updateState = () => { + updateState = (setIt = true) => { let { date } = 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) @@ -60,7 +60,7 @@ export default class TimeExactWrapper extends React.Component { dt, ...formatTimeExact(dt, 2, this.props.shorter) } - this.setState(state) + if (setIt) this.setState(state) return state } @@ -76,7 +76,7 @@ export default class TimeExactWrapper extends React.Component { render() { const { className, tooltipRender, contentRender } = this.props let state = this.state - state = state || this.updateState() + state = state || this.updateState(false) let { dt, result } = state let tooltip = dt.toLocaleString() tooltip = tooltipRender ? tooltipRender(tooltip) : tooltip diff --git a/app/components/elements/nft/NFTTokenItem.jsx b/app/components/elements/nft/NFTTokenItem.jsx index e39a870..b732e5a 100644 --- a/app/components/elements/nft/NFTTokenItem.jsx +++ b/app/components/elements/nft/NFTTokenItem.jsx @@ -6,6 +6,7 @@ import tt from 'counterpart' import { Asset } from 'golos-lib-js/lib/utils' import DropdownMenu from 'app/components/elements/DropdownMenu' +import FitText from 'app/components/elements/FitText' import Icon from 'app/components/elements/Icon' import NFTTokenSellPopup from 'app/components/elements/nft/NFTTokenSellPopup' import PriceIcon from 'app/components/elements/nft/PriceIcon' @@ -157,6 +158,10 @@ class NFTTokenItem extends Component { const isCollection = page === 'collection' const isMarket = page === 'market' + const preventNavigate = (e) => { + e.preventDefault() + } + let myBet if (my_bet) { const pr = Asset(my_bet.price) @@ -171,7 +176,8 @@ class NFTTokenItem extends Component { }) } myBet = + title={tt('nft_tokens_jsx.you_bet_is') + pr.floatString} + onClick={preventNavigate}> { return pr.amountFloat }} asset={pr} assets={assets} /> @@ -193,7 +199,8 @@ class NFTTokenItem extends Component { }) } myOffer = + title={tt('nft_tokens_jsx.you_offer_is') + pr.floatString} + onClick={preventNavigate}> { return pr.amountFloat }} asset={pr} assets={assets} /> @@ -257,10 +264,10 @@ class NFTTokenItem extends Component { let titleFont, titleTop, titleBottom, titleTitle const titleLen = titleShr.length if (titleLen > 23) { - titleFont = '90%' + titleFont = '80%' titleTop = titleBottom = '0.42rem' } - if (titleLen > 35) { + if (titleLen > 32) { titleShr = titleShr.substring(0, 30) + '...' titleTitle = data.title } @@ -278,8 +285,8 @@ class NFTTokenItem extends Component { {myBet} {myOffer}
-
- {titleShr} +
+
diff --git a/app/components/modules/nft/NFTMyOrders.jsx b/app/components/modules/nft/NFTMyOrders.jsx index 64d3810..4c68d8f 100644 --- a/app/components/modules/nft/NFTMyOrders.jsx +++ b/app/components/modules/nft/NFTMyOrders.jsx @@ -23,11 +23,11 @@ const wrapAsTable = (immData, onRender, emptyHint) => { res.push(onRender(item)) } if (res.length) { - res = + res =
{res}
} else { - res = emptyHint + res =
{emptyHint}
} return res @@ -37,11 +37,15 @@ class NFTMyOrders extends React.Component { state = {} componentDidMount() { - this.refetch() + this.refetch(true) } - refetch = () => { - this.props.fetchNftOrders() + refetch = (init = false) => { + const { isModal } = this.props + this.props.fetchNftOrders(isModal && 'GOLOS') + if (!init && isModal) { + this.props.fetchState() // update nft_hold_balance in wallet + } } cancelOrder = (e, owner, order_id, tokenTitle) => { @@ -161,22 +165,63 @@ class NFTMyOrders extends React.Component { } + _renderTabs = () => { + const { section } = this.state + + let offers =

{tt('nft_my_orders_jsx.offers')}

+ let bets =

{tt('nft_my_orders_jsx.bets')}

+ + const wrapLink = (item, tab) => { + const switchTab = (e) => { + e.preventDefault() + this.setState({ + section: tab + }) + } + return switchTab(e)}>{item} + } + + if (section === 'bets') { + offers = wrapLink(offers, 'offers') + } else { + bets = wrapLink(bets, 'bets') + } + + return
+ {offers} +

 / 

+ {bets} +
+ } + _renderOffers = (assets) => { - let { my_nft_offers } = this.props - return wrapAsTable(my_nft_offers, no => this._renderOffer(no, assets), + let { my_nft_offers, isModal } = this.props + + const offers = wrapAsTable(my_nft_offers, no => this._renderOffer(no, assets), tt('nft_my_orders_jsx.offers_empty')) + + return + {!isModal &&

{tt('nft_my_orders_jsx.offers')}

} + {offers} +
} _renderBets = (assets) => { - let { my_nft_bets } = this.props + let { my_nft_bets, isModal } = this.props - return wrapAsTable(my_nft_bets, nb => this._renderBet(nb, assets), + const bets = wrapAsTable(my_nft_bets, nb => this._renderBet(nb, assets), tt('nft_my_orders_jsx.bets_empty')) + + return + {!isModal &&

{tt('nft_my_orders_jsx.bets')}

} + {bets} +
} render() { let { my_nft_offers, my_nft_bets, nft_assets, current_user, account, isModal } = this.props + const { section } = this.state const username = session.load().currentName if (!isModal && (!username || !account || username !== account.name)) { @@ -199,11 +244,10 @@ class NFTMyOrders extends React.Component { return (
-

{tt('nft_my_orders_jsx.offers')}

- {this._renderOffers(assets)} -
-

{tt('nft_my_orders_jsx.bets')}

- {this._renderBets(assets)} + {isModal && this._renderTabs()} + {(!isModal || section !== 'bets') && this._renderOffers(assets)} + {!isModal &&
} + {(!isModal || section === 'bets') && this._renderBets(assets)}
); @@ -224,8 +268,12 @@ export default connect( } }, dispatch => ({ - fetchNftOrders: () => { - dispatch(g.actions.fetchNftOrders({ })) + fetchState: () => { + const pathname = window.location.pathname + dispatch({type: 'FETCH_STATE', payload: {pathname}}) + }, + fetchNftOrders: (sym = undefined) => { + dispatch(g.actions.fetchNftOrders({ sym })) }, cancelOrder: ( owner, order_id, tokenTitle, successCallback, errorCallback diff --git a/app/components/modules/nft/NFTMyOrders.scss b/app/components/modules/nft/NFTMyOrders.scss index 05ffa42..1d506bf 100644 --- a/app/components/modules/nft/NFTMyOrders.scss +++ b/app/components/modules/nft/NFTMyOrders.scss @@ -8,4 +8,13 @@ .button { margin-bottom: 0px; } + + h4 { + display: inline-block; + } + a { + h4 { + text-decoration: underline; + } + } } diff --git a/app/components/pages/nft/NFTMarketPage.jsx b/app/components/pages/nft/NFTMarketPage.jsx index 70b13b3..e96529b 100644 --- a/app/components/pages/nft/NFTMarketPage.jsx +++ b/app/components/pages/nft/NFTMarketPage.jsx @@ -67,7 +67,8 @@ class NFTMarketPage extends React.Component { const username = currentUser && currentUser.get('username') - content =
+ content =
+
AvaSlon21veka
{items} {next_from ?