bug fixes and UX improvements

- fixed incorrect dat-time shown with orders
-- fixed percent buttons not working for selling FLO
-- data refreshes after successful transactions
-- fixed balance overflow
This commit is contained in:
sairaj mote 2021-10-23 02:38:30 +05:30
parent 160102ea66
commit 1a4fc432e3

View File

@ -116,20 +116,20 @@
<strip-option value="sell">Sell</strip-option> <strip-option value="sell">Sell</strip-option>
</strip-select> </strip-select>
</div> </div>
<sm-input id="get_price" variant="outlined" placeholder="Max price (₹)" type="number" step="0.00001" <sm-input id="get_price" variant="outlined" placeholder="Max price (₹)" type="number" step="0.01"
required hiderequired animate> required hiderequired animate>
</sm-input> </sm-input>
<sm-input id="get_quantity" variant="outlined" placeholder="Quantity (FLO)" type="number" <sm-input id="get_quantity" variant="outlined" placeholder="Quantity (FLO)" type="number" step="0.0001"
step="0.00000001" required hiderequired animate></sm-input> required hiderequired animate></sm-input>
<sm-input id="get_total" variant="outlined" placeholder="Total (₹)" type="number" min="0.01" step="0.01" <sm-input id="get_total" variant="outlined" placeholder="Total (₹)" type="number" min="0.01" step="0.01"
required hiderequired animate> required hiderequired animate>
</sm-input> </sm-input>
<div id="quantity_selector" class="flex align-center"> <div id="quantity_selector" class="flex align-center">
<span id="quantity_type">Rupee</span> <span id="quantity_type">Rupee</span>
<button class="button" value="25">25%</button> <button class="button" value="0.25">25%</button>
<button class="button" value="50">50%</button> <button class="button" value="0.5">50%</button>
<button class="button" value="75">75%</button> <button class="button" value="0.75">75%</button>
<button class="button" value="100">100%</button> <button class="button" value="1">100%</button>
</div> </div>
<div id="trade_button_wrapper" class="stateful-button-wrapper flex align-center justify-center"> <div id="trade_button_wrapper" class="stateful-button-wrapper flex align-center justify-center">
<sm-button id="trade_button" class="uppercase w-100" variant="primary" onclick="tradeFlo()">BUY FLO <sm-button id="trade_button" class="uppercase w-100" variant="primary" onclick="tradeFlo()">BUY FLO
@ -224,25 +224,27 @@
</div> </div>
<div class="grid gap-0-5"> <div class="grid gap-0-5">
<h4>Balance</h4> <h4>Balance</h4>
<div class="balance-card"> <div class="grid gap-1">
<div class="balance-card__icon"> <div class="balance-card">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <div class="balance-card__icon">
<path <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
d="M16.36,15.39c1.83,0,4.26-2.49,4.36-4.74-5.65-.19-4.91.47-7.28,2.39,2.19-2.4,1.42-7.79-1.43-10V6.17c2.33,1.49,2.21,5.14,0,7.15-2.23-2-2.27-5.69,0-7.15V3c-2.83,2.26-3.62,7.66-1.44,10-2.36-1.93-1.63-2.58-7.28-2.39.1,2.26,2.55,4.73,4.36,4.74,0,0-1.93.22-2.74-2.62,2.38-.37,4.29-.14,6.28,2-.79-.11-4.89,1.13-4.38,3.26.53.06,3,.3,3.58-.83-.17.18-1.25.5-1.53.05.38-1.39,2.32-2,2.32-2-1,1.82-.48,4.63.82,5.72,1.31-1.08,1.8-3.95.82-5.72,0,0,1.95.6,2.32,2-.29.46-1.36.12-1.53-.05.58,1.14,3.06.88,3.58.83.49-2.17-3.58-3.36-4.38-3.26,2-2.17,3.92-2.39,6.28-2C18.3,15.62,16.36,15.39,16.36,15.39ZM12,19.46c-.91-.79-.5-3,0-3.59C12.5,16.45,12.91,18.66,12,19.46Z" /> <path
</svg> d="M16.36,15.39c1.83,0,4.26-2.49,4.36-4.74-5.65-.19-4.91.47-7.28,2.39,2.19-2.4,1.42-7.79-1.43-10V6.17c2.33,1.49,2.21,5.14,0,7.15-2.23-2-2.27-5.69,0-7.15V3c-2.83,2.26-3.62,7.66-1.44,10-2.36-1.93-1.63-2.58-7.28-2.39.1,2.26,2.55,4.73,4.36,4.74,0,0-1.93.22-2.74-2.62,2.38-.37,4.29-.14,6.28,2-.79-.11-4.89,1.13-4.38,3.26.53.06,3,.3,3.58-.83-.17.18-1.25.5-1.53.05.38-1.39,2.32-2,2.32-2-1,1.82-.48,4.63.82,5.72,1.31-1.08,1.8-3.95.82-5.72,0,0,1.95.6,2.32,2-.29.46-1.36.12-1.53-.05.58,1.14,3.06.88,3.58.83.49-2.17-3.58-3.36-4.38-3.26,2-2.17,3.92-2.39,6.28-2C18.3,15.62,16.36,15.39,16.36,15.39ZM12,19.46c-.91-.79-.5-3,0-3.59C12.5,16.45,12.91,18.66,12,19.46Z" />
</svg>
</div>
<div class="balance-card__token">FLO</div>
<div id="flo_balance"></div>
</div> </div>
<div class="balance-card__token">FLO</div> <div class="balance-card">
<div id="flo_balance"></div> <div class="balance-card__icon">
</div> <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<div class="balance-card"> <path
<div class="balance-card__icon"> d="M15.3,4.91a4.78,4.78,0,0,0-.39-.5l3.14,0L18.75,2H6L5.25,4.6H9a4.22,4.22,0,0,1,3.06,1,3.16,3.16,0,0,1,.75,1.24H5.93L5.25,9.22h7.62a3.15,3.15,0,0,1-.34.82,3,3,0,0,1-1.37,1.17,5.34,5.34,0,0,1-2.2.4H5.5l0,1.9,7,8.49h3.56v-.17L9.68,14l.09,0a8.07,8.07,0,0,0,3.65-1,5,5,0,0,0,2-2.09A6.29,6.29,0,0,0,16,9.22h2.1l.69-2.42H15.93A5.93,5.93,0,0,0,15.3,4.91Z" />
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> </svg>
<path </div>
d="M15.3,4.91a4.78,4.78,0,0,0-.39-.5l3.14,0L18.75,2H6L5.25,4.6H9a4.22,4.22,0,0,1,3.06,1,3.16,3.16,0,0,1,.75,1.24H5.93L5.25,9.22h7.62a3.15,3.15,0,0,1-.34.82,3,3,0,0,1-1.37,1.17,5.34,5.34,0,0,1-2.2.4H5.5l0,1.9,7,8.49h3.56v-.17L9.68,14l.09,0a8.07,8.07,0,0,0,3.65-1,5,5,0,0,0,2-2.09A6.29,6.29,0,0,0,16,9.22h2.1l.69-2.42H15.93A5.93,5.93,0,0,0,15.3,4.91Z" /> <div class="balance-card__token">Rupee</div>
</svg> <div id="rupee_balance"></div>
</div> </div>
<div class="balance-card__token">Rupee</div>
<div id="rupee_balance"></div>
</div> </div>
</div> </div>
</section> </section>
@ -443,11 +445,11 @@
<span class="available-balance"></span> <span class="available-balance"></span>
</template> </template>
<template id="locked_balance_template"> <template id="locked_balance_template">
<div> <div class="grid">
<span class="label">Locked</span> <span class="label">Locked</span>
<span class="locked-balance"></span> <span class="locked-balance"></span>
</div> </div>
<div> <div class="grid">
<span class="label">Available</span> <span class="label">Available</span>
<span class="available-balance"></span> <span class="available-balance"></span>
</div> </div>
@ -737,7 +739,7 @@
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
buttons[0].onclick = () => { buttons[0].onclick = () => {
hidePopup() hidePopup()
reject(null); return (null);
} }
buttons[1].onclick = () => { buttons[1].onclick = () => {
const value = getRef('prompt_input').value; const value = getRef('prompt_input').value;
@ -769,21 +771,13 @@
} }
} }
function getFormattedTime(time, relative) { function getFormattedTime(timeString, relative) {
try { try {
if (String(time).indexOf('_')) const [date, time] = timeString.split('T')
time = String(time).split('_')[0] const [year, month, day] = date.split('-').map(v => parseInt(v))
const intTime = parseInt(time) let [hours, minutes] = time.split(':').map(v => parseInt(v))
if (String(intTime).length < 13) const currentTime = new Date()
time *= 1000 const currentTimeFrag = currentTime.toString().split(' ')
let timeFrag = new Date(intTime).toString().split(' '),
day = timeFrag[0],
month = timeFrag[1],
date = timeFrag[2],
year = timeFrag[3],
minutes = new Date(intTime).getMinutes(),
hours = new Date(intTime).getHours(),
currentTime = new Date().toString().split(' ')
minutes = minutes < 10 ? `0${minutes}` : minutes minutes = minutes < 10 ? `0${minutes}` : minutes
let finalHours = ``; let finalHours = ``;
@ -797,25 +791,25 @@
finalHours = hours >= 12 ? `${finalHours} PM` : `${finalHours} AM` finalHours = hours >= 12 ? `${finalHours} PM` : `${finalHours} AM`
if (relative) { if (relative) {
if (year == currentYear) { if (year == currentYear) {
if (currentTime[1] === month) { if ((currentTime.getMonth() + 1) === month) {
const dateDiff = (parseInt(currentTime[2]) - parseInt(date)) const dateDiff = (parseInt(currentTimeFrag[2]) - parseInt(day))
if (dateDiff === 0) if (dateDiff === 0)
return `${finalHours}`; return `${finalHours}`;
else if (dateDiff === 1) else if (dateDiff === 1)
return `Yesterday`; return `Yesterday`;
else if (dateDiff > 1 && dateDiff < 8) else if (dateDiff > 1 && dateDiff < 8)
return currentTime[0]; return currentTimeFrag[0];
else else
return ` ${date} ${month}`; return ` ${day} ${month}`;
} }
else else
return ` ${date} ${month}`; return ` ${day} ${month}`;
} }
else else
return `${month} ${year}`; return `${month} ${year}`;
} }
else else
return `${finalHours}, ${month} ${date} ${year}`; return `${finalHours}, ${month} ${day} ${year}`;
} catch (e) { } catch (e) {
console.error(e); console.error(e);
return time; return time;
@ -1064,6 +1058,7 @@
} }
getRef('trade_button_wrapper').append(getRef('success_template').content.cloneNode(true)) getRef('trade_button_wrapper').append(getRef('success_template').content.cloneNode(true))
notify(`Placed ${tradeType} order`, 'success') notify(`Placed ${tradeType} order`, 'success')
refresh()
} }
catch (err) { catch (err) {
getRef('trade_button_wrapper').append(getRef('failure_template').content.cloneNode(true)) getRef('trade_button_wrapper').append(getRef('failure_template').content.cloneNode(true))
@ -1086,18 +1081,19 @@
if (e.target.closest('button')) { if (e.target.closest('button')) {
const target = e.target.closest('button') const target = e.target.closest('button')
const unitValue = parseFloat(getRef('get_price').value) const unitValue = parseFloat(getRef('get_price').value)
const fraction = parseInt(target.value) / 100 const fraction = parseInt(target.value)
if (tradeType === 'buy') { if (tradeType === 'buy') {
getRef('get_total').value = parseFloat((fraction * balance.rupee).toFixed(2)) getRef('get_total').value = parseFloat((fraction * balance.rupee).toFixed(2))
getRef('get_quantity').value = parseFloat(((balance.rupee * fraction) / unitValue).toFixed(5)) getRef('get_quantity').value = parseFloat(((balance.rupee * fraction) / unitValue).toFixed(4))
} else { } else {
getRef('get_total').value = parseFloat(((fraction * balance.flo) * rate.flo).toFixed(2)) console.log(fraction, balance.flo, floExchangeRate)
getRef('get_quantity').value = parseFloat((balance.flo * fraction).toFixed(5)) getRef('get_total').value = parseFloat((fraction * balance.flo * floExchangeRate).toFixed(2))
getRef('get_quantity').value = parseFloat((balance.flo * fraction).toFixed(4))
} }
} }
}) })
getRef('get_price').addEventListener('keyup', e => { getRef('get_price').addEventListener('keyup', e => {
const unitValue = parseFloat(getRef('get_price').value) || rate.flo const unitValue = parseFloat(getRef('get_price').value) || floExchangeRate
const quantity = parseFloat(getRef('get_quantity').value) || 0 const quantity = parseFloat(getRef('get_quantity').value) || 0
getRef('get_total').value = parseFloat((quantity * unitValue).toFixed(2)) || 0 getRef('get_total').value = parseFloat((quantity * unitValue).toFixed(2)) || 0
}) })
@ -1107,7 +1103,7 @@
}) })
getRef('get_total').addEventListener('keyup', e => { getRef('get_total').addEventListener('keyup', e => {
const unitValue = parseFloat(getRef('get_price').value) const unitValue = parseFloat(getRef('get_price').value)
getRef('get_quantity').value = parseFloat((parseFloat(e.target.value) / unitValue).toFixed(5)) || 0 getRef('get_quantity').value = parseFloat((parseFloat(e.target.value) / unitValue).toFixed(4)) || 0
}) })
getRef('wallet_actions').addEventListener('click', e => { getRef('wallet_actions').addEventListener('click', e => {
if (e.target.closest('.button')) { if (e.target.closest('.button')) {
@ -1189,9 +1185,9 @@
showWalletResult('success', `Sent ${asset} deposit request`, 'This may take upto 30 mins to reflect in your wallet.') showWalletResult('success', `Sent ${asset} deposit request`, 'This may take upto 30 mins to reflect in your wallet.')
} else { } else {
if (asset === 'FLO') { if (asset === 'FLO') {
await withdrawFLO(quantity, await proxy.secret) await withdrawFLO(quantity, proxy.secret)
} else { } else {
await withdrawRupee(quantity, await proxy.secret) await withdrawRupee(quantity, proxy.secret)
} }
showWalletResult('success', `Sent ${asset} withdraw request`, 'This may take upto 30 mins to reflect in your wallet.') showWalletResult('success', `Sent ${asset} withdraw request`, 'This may take upto 30 mins to reflect in your wallet.')
} }
@ -1204,7 +1200,6 @@
} }
}) })
const selectedOrders = new Map()
const slideInLeft = [ const slideInLeft = [
{ {
opacity: 0, opacity: 0,
@ -1265,6 +1260,8 @@
transform: 'translateY(-1rem)' transform: 'translateY(-1rem)'
}, },
] ]
const selectedOrders = new Map()
getRef('orders_list').addEventListener('change', e => { getRef('orders_list').addEventListener('change', e => {
const animOptions = { const animOptions = {
duration: 150, duration: 150,
@ -1363,6 +1360,7 @@
target.remove() target.remove()
}, 200); }, 200);
} }
refresh()
}) })
.catch(err => notify(err.data, 'error')) .catch(err => notify(err.data, 'error'))
} }
@ -1377,7 +1375,7 @@
try { try {
let proxy_secret = await proxy.secret; let proxy_secret = await proxy.secret;
await Promise.all( await Promise.all(
selectedOrders.map((type, id) => cancelOrder(type, id, proxy_secret)) [...selectedOrders].map((id, type) => cancelOrder(type, id, proxy_secret))
) )
selectedOrders.forEach((type, id) => { selectedOrders.forEach((type, id) => {
getRef('orders_list').querySelector(`[data-id="${id}"]`).remove() getRef('orders_list').querySelector(`[data-id="${id}"]`).remove()
@ -1393,12 +1391,12 @@
} }
function renderUserOrders() { function renderUserOrders() {
const { buyOrders, sellOrders, transactions } = accountDetails let { buyOrders, sellOrders, transactions } = accountDetails
getRef('orders_list').innerHTML = ''; getRef('orders_list').innerHTML = '';
const frag = document.createDocumentFragment() const frag = document.createDocumentFragment()
const ordersType = getRef('my_orders_category_selector').value const ordersType = getRef('my_orders_category_selector').value
if (ordersType === 'open') { if (ordersType === 'open') {
const allOpenOrders = [...(buyOrders || myBuyOrders), ...(sellOrders || mySellOrders)].sort((a, b) => b.time_placed - a.time_placed) const allOpenOrders = [...buyOrders, ...sellOrders].sort((a, b) => new Date(b.time_placed).getTime() - new Date(a.time_placed).getTime())
allOpenOrders.forEach(order => { allOpenOrders.forEach(order => {
const { id, quantity, minPrice = undefined, maxPrice = undefined, time_placed } = order const { id, quantity, minPrice = undefined, maxPrice = undefined, time_placed } = order
const orderDetails = { const orderDetails = {
@ -1446,7 +1444,7 @@
if (ordersType === 'open') { if (ordersType === 'open') {
try { try {
const [buyOrders, sellOrders] = await Promise.all([getBuyList(), getSellList()]) const [buyOrders, sellOrders] = await Promise.all([getBuyList(), getSellList()])
const allOpenOrders = [...(buyOrders), ...(sellOrders)].sort((a, b) => b.time_placed - a.time_placed) const allOpenOrders = [...(buyOrders), ...(sellOrders)].sort((a, b) => new Date(b.time_placed).getTime() - new Date(a.time_placed).getTime())
allOpenOrders.forEach(order => { allOpenOrders.forEach(order => {
const { floID, quantity, minPrice = undefined, maxPrice = undefined, time_placed } = order const { floID, quantity, minPrice = undefined, maxPrice = undefined, time_placed } = order
const orderDetails = { const orderDetails = {
@ -1565,7 +1563,6 @@
Reject("Unable to fetch Proxy secret"); Reject("Unable to fetch Proxy secret");
} }
}; };
let tmp = localStorage.getItem("proxy_secret"); let tmp = localStorage.getItem("proxy_secret");
if (typeof tmp !== "string") if (typeof tmp !== "string")
Reject("Unable to fetch Proxy secret"); Reject("Unable to fetch Proxy secret");
@ -1580,6 +1577,7 @@
setValues(tmp); setValues(tmp);
} catch (error) { } catch (error) {
Reject("Incorrect Password! Password Required for making transactions"); Reject("Incorrect Password! Password Required for making transactions");
} }
}).catch(_ => Reject("Password Required for making transactions")); }).catch(_ => Reject("Password Required for making transactions"));
} else } else
@ -1588,9 +1586,10 @@
} }
} }
let floExchangeRate = 0
function updateRate() { function updateRate() {
getRate().then(rate => { getRate().then(rate => {
rate.flo = rate floExchangeRate = parseFloat(rate)
getRef('flo_rate').textContent = formatAmount(parseFloat(rate)) getRef('flo_rate').textContent = formatAmount(parseFloat(rate))
getRef('get_price').value = parseFloat(parseFloat(rate).toFixed(2)) getRef('get_price').value = parseFloat(parseFloat(rate).toFixed(2))
}).catch(error => console.error(error)) }).catch(error => console.error(error))
@ -1606,23 +1605,22 @@
account(); account();
} }
function showBalance(containerId, availableBalance = 0, lockedBalance = 0) { function showBalance(type, availableBalance = 0, lockedBalance = 0) {
getRef(containerId).innerHTML = '' getRef(`${type}_balance`).innerHTML = ''
const templateToClone = lockedBalance ? 'locked_balance_template' : 'net_balance_template'; const templateToClone = lockedBalance ? 'locked_balance_template' : 'net_balance_template';
const card = getRef(templateToClone).content.cloneNode(true) const card = getRef(templateToClone).content.cloneNode(true)
card.querySelector('.available-balance').textContent = availableBalance card.querySelector('.available-balance').textContent = type === 'flo' ? parseFloat(availableBalance.toFixed(4)) : formatAmount(availableBalance)
if (lockedBalance) { if (lockedBalance) {
card.querySelector('.locked-balance').textContent = lockedBalance card.querySelector('.locked-balance').textContent = type === 'flo' ? parseFloat(lockedBalance.toFixed(4)) : formatAmount(lockedBalance)
} }
getRef(containerId).className = lockedBalance ? 'grid balance-card__amount-wrapper' : '' getRef(`${type}_balance`).className = lockedBalance ? 'grid balance-card__amount-wrapper' : ''
getRef(containerId).parentNode.className = `balance-card ${lockedBalance ? 'is-locked' : ''}` getRef(`${type}_balance`).parentNode.className = `balance-card ${lockedBalance ? 'is-locked' : ''}`
getRef(containerId).append(card) getRef(`${type}_balance`).append(card)
} }
const balance = {} const balance = {}
let accountDetails = {} let accountDetails = {}
function account() { function account() {
getAccount().then(acc => { getAccount().then(acc => {
getRef("login_form").classList.add('hide-completely') getRef("login_form").classList.add('hide-completely')
@ -1641,14 +1639,14 @@
console.debug("FLO", flo_total, flo_locked, flo_net); console.debug("FLO", flo_total, flo_locked, flo_net);
balance.flo = flo_net balance.flo = flo_net
showBalance("flo_balance", flo_net, flo_locked) showBalance("flo", flo_net, flo_locked,)
//Rupee Balance //Rupee Balance
let rupee_total = acc.rupee_total; let rupee_total = acc.rupee_total;
let rupee_locked = acc.buyOrders.reduce((a, x) => a + x.quantity * x.maxPrice, 0); let rupee_locked = acc.buyOrders.reduce((a, x) => a + x.quantity * x.maxPrice, 0);
let rupee_net = rupee_total - rupee_locked; let rupee_net = rupee_total - rupee_locked;
console.debug("RUPEE", rupee_total, rupee_locked, rupee_net); console.debug("RUPEE", rupee_total, rupee_locked, rupee_net);
balance.rupee = rupee_net balance.rupee = rupee_net
showBalance("rupee_balance", rupee_net, rupee_locked) showBalance("rupee", rupee_net, rupee_locked)
//My orders //My orders
renderUserOrders(); renderUserOrders();
proxy.secret.then(_ => null).catch(_ => null); proxy.secret.then(_ => null).catch(_ => null);
@ -1684,10 +1682,7 @@
}, },
logout() { logout() {
getConfirmation('Log out?', { getConfirmation('Log out?', { cancelText: 'Stay', confirmText: 'Log out' }).then(res => {
cancelText: 'Stay',
confirmText: 'Log out'
}).then(res => {
if (res) { if (res) {
logout().then(result => { logout().then(result => {
console.warn(result); console.warn(result);