Claim Reward dialog UI improvements

staking
Vadim 5 years ago committed by Victor Baranov
parent 93acfb3a6f
commit f29e7e216f
  1. 17
      apps/block_scout_web/assets/css/components/stakes/_modal_claim_reward.scss
  2. 10
      apps/block_scout_web/assets/js/lib/modals.js
  3. 14
      apps/block_scout_web/assets/js/pages/stakes.js
  4. 53
      apps/block_scout_web/assets/js/pages/stakes/claim_reward.js
  5. 4
      apps/block_scout_web/lib/block_scout_web/channels/stakes_channel.ex
  6. 16
      apps/block_scout_web/lib/block_scout_web/templates/stakes/_stakes_modal_claim_reward_content.html.eex

@ -20,20 +20,17 @@
&.m-b-0 {
margin-bottom: 0;
}
&.left {
width: 49%;
float: left;
}
&.right {
width: 49%;
float: right;
}
}
textarea {
background: #fff!important;
height: 38px;
}
.amounts {
display: grid;
grid-template-rows: 1fr;
grid-template-columns: 1fr 80px;
grid-gap: 2vw;
}
}

@ -87,7 +87,7 @@ export function lockModal ($modal, $submitButton = null, spinnerText = '') {
modalLocked = true
}
export function unlockModal ($modal, $submitButton = null) {
export function unlockModal($modal, $submitButton = null) {
$modal.find('.close-modal').attr('disabled', false)
const $button = $submitButton || $modal.find('.btn-add-full')
@ -106,28 +106,28 @@ export function unlockModal ($modal, $submitButton = null) {
modalLocked = false
}
export function openErrorModal (title, text, unclosable) {
export function openErrorModal(title, text, unclosable) {
const $modal = $('#errorStatusModal')
$modal.find('.modal-status-title').text(title)
$modal.find('.modal-status-text').html(text)
openModal($modal, unclosable)
}
export function openWarningModal (title, text) {
export function openWarningModal(title, text) {
const $modal = $('#warningStatusModal')
$modal.find('.modal-status-title').text(title)
$modal.find('.modal-status-text').html(text)
openModal($modal)
}
export function openSuccessModal (title, text) {
export function openSuccessModal(title, text) {
const $modal = $('#successStatusModal')
$modal.find('.modal-status-title').text(title)
$modal.find('.modal-status-text').html(text)
openModal($modal)
}
export function openQuestionModal (title, text, acceptCallback = null, exceptCallback = null, acceptText = 'Yes', exceptText = 'No') {
export function openQuestionModal(title, text, acceptCallback = null, exceptCallback = null, acceptText = 'Yes', exceptText = 'No') {
const $modal = $('#questionStatusModal')
const $closeButton = $modal.find('.close-modal')

@ -202,7 +202,7 @@ if ($stakesPage.length) {
type: 'RECEIVED_CONTRACTS',
stakingContract,
blockRewardContract,
tokenDecimals: parseInt(msg.token_decimals),
tokenDecimals: parseInt(msg.token_decimals, 10),
tokenSymbol: msg.token_symbol
})
})
@ -259,6 +259,11 @@ if ($stakesPage.length) {
initialize(store)
}
function hideCurrentModal() {
const $modal = currentModal()
if ($modal) $modal.modal('hide')
}
function initialize(store) {
if (window.ethereum) {
const web3 = new Web3(window.ethereum)
@ -354,10 +359,7 @@ function setAccount(account, store) {
).receive('ok', () => {
$addressField.html(account)
refreshPageWrapper(store)
const $modal = currentModal()
if ($modal) {
$modal.modal('hide')
}
hideCurrentModal()
}).receive('error', () => {
openErrorModal('Change account', errorMsg, true)
}).receive('timeout', () => {
@ -366,6 +368,8 @@ function setAccount(account, store) {
}
function setNetwork(networkId, store) {
hideCurrentModal()
let network = {
id: networkId,
authorized: false

@ -123,9 +123,9 @@ function onPoolsFound($modal, $modalBody, channel, store) {
$poolsDropdown.blur()
$('textarea', $poolInfo).val(epochs)
$('#token-reward-sum', $poolInfo).html(tokenRewardSum).data('default', tokenRewardSum)
$('#native-reward-sum', $poolInfo).html(nativeRewardSum).data('default', nativeRewardSum)
$('#tx-gas-limit', $poolInfo).html('~' + gasLimit).data('default', gasLimit)
$('#token-reward-sum', $poolInfo).text(tokenRewardSum).data('default', tokenRewardSum)
$('#native-reward-sum', $poolInfo).text(nativeRewardSum).data('default', nativeRewardSum)
$('#tx-gas-limit', $poolInfo).text('~' + gasLimit).data('default', gasLimit)
$('#epoch-choice-all', $poolInfo).click()
$specifiedEpochsText.val('')
$poolInfo.removeClass('hidden')
@ -217,7 +217,15 @@ function onPoolsFound($modal, $modalBody, channel, store) {
function claimStarted() {
status = 'claiming'
hideInputError($submitButton)
lockUI(true, $modal, $submitButton, $poolsDropdown, $epochChoiceRadio, $specifiedEpochsText);
lockUI(
true,
$modal,
$submitButton,
$poolsDropdown,
$epochChoiceRadio,
$specifiedEpochsText,
'Please, sign transaction in MetaMask'
)
const gasLimit = parseInt($('#tx-gas-limit', $modalBody).text().replace(/~/g, '').trim(), 10)
const state = store.getState()
@ -238,22 +246,31 @@ function onPoolsFound($modal, $modalBody, channel, store) {
} else {
stakingContract.methods.claimReward(epochs, poolStakingAddress).send({
from,
gasPrice: 1000000000,
gas: Math.ceil(gasLimit * 1.2)
gasPrice: web3.utils.toWei('1', 'gwei'),
gas: Math.ceil(gasLimit * 1.2) // +20% reserve to ensure enough gas
}, async function(error, txHash) {
if (error) {
claimFinished(error.message)
} else {
try {
let tx
let currentBlockNumber
const maxWaitBlocks = 6
const startBlockNumber = (await web3.eth.getBlockNumber()) - 0
const finishBlockNumber = startBlockNumber + maxWaitBlocks
do {
await sleep(5000)
await sleep(5) // seconds
tx = await web3.eth.getTransactionReceipt(txHash)
} while (tx === null)
if (tx.status === true || tx.status === '0x1') {
claimFinished()
currentBlockNumber = await web3.eth.getBlockNumber()
} while (tx === null && currentBlockNumber <= finishBlockNumber)
if (tx) {
if (tx.status === true || tx.status === '0x1') {
claimFinished()
} else {
claimFinished('Transaction reverted')
}
} else {
claimFinished('Transaction reverted')
claimFinished(`Your transaction was not mined in ${maxWaitBlocks} blocks. Please, try again with the increased gas price or fixed nonce (use Reset Account feature of MetaMask).`)
}
} catch (e) {
claimFinished(e.message)
@ -275,9 +292,9 @@ function onPoolsFound($modal, $modalBody, channel, store) {
})
}
function lockUI(lock, $modal, $button, $poolsDropdown, $epochChoiceRadio, $specifiedEpochsText) {
function lockUI(lock, $modal, $button, $poolsDropdown, $epochChoiceRadio, $specifiedEpochsText, spinnerText) {
if (lock) {
lockModal($modal, $button)
lockModal($modal, $button, spinnerText)
} else {
unlockModal($modal, $button)
}
@ -286,8 +303,8 @@ function lockUI(lock, $modal, $button, $poolsDropdown, $epochChoiceRadio, $speci
$specifiedEpochsText.prop('disabled', lock)
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
function sleep(seconds) {
return new Promise(resolve => setTimeout(resolve, seconds * 1000))
}
function showButton(type, $modalBody, calculations) {
@ -325,8 +342,8 @@ function expandEpochsToArray(epochs) {
ranges = ranges.map((v) => {
if (v.indexOf('-') > -1) {
v = v.split('-')
v[0] = parseInt(v[0])
v[1] = parseInt(v[1])
v[0] = parseInt(v[0], 10)
v[1] = parseInt(v[1], 10)
v.sort((a, b) => a - b)
const min = v[0]
const max = v[1]
@ -336,7 +353,7 @@ function expandEpochsToArray(epochs) {
}
return expanded
} else {
return parseInt(v)
return parseInt(v, 10)
}
})
ranges = ranges.reduce((acc, val) => acc.concat(val), []) // similar to ranges.flat()

@ -527,8 +527,8 @@ defmodule BlockScoutWeb.StakesChannel do
coin = %Token{symbol: Explorer.coin(), decimals: Decimal.new(18)}
push(socket, "claim_reward_recalculations", %{
token_reward_sum: StakesHelpers.format_token_amount(amounts.token_reward_sum, token, digits: 5, ellipsize: false, symbol: false),
native_reward_sum: StakesHelpers.format_token_amount(amounts.native_reward_sum, coin, digits: 5, ellipsize: false, symbol: false),
token_reward_sum: StakesHelpers.format_token_amount(amounts.token_reward_sum, token, digits: token.decimals, ellipsize: false, symbol: false),
native_reward_sum: StakesHelpers.format_token_amount(amounts.native_reward_sum, coin, digits: coin.decimals, ellipsize: false, symbol: false),
gas_limit: gas_limit,
error: error
})

@ -6,16 +6,18 @@
<option disabled="disabled" selected="selected"><%= gettext("Choose Pool") %></option>
<%= for {pool_staking_address, data} <- @pools do %>
<%
token_reward_sum = format_token_amount(data.token_reward_sum, @token, digits: 5, ellipsize: false, symbol: false)
native_reward_sum = format_token_amount(data.native_reward_sum, @coin, digits: 5, ellipsize: false, symbol: false)
token_reward_sum = format_token_amount(data.token_reward_sum, @token, digits: @token.decimals, ellipsize: false, symbol: false)
token_reward_sum_short = format_token_amount(data.token_reward_sum, @token, digits: 5, ellipsize: false, symbol: false)
native_reward_sum = format_token_amount(data.native_reward_sum, @coin, digits: @coin.decimals, ellipsize: false, symbol: false)
native_reward_sum_short = format_token_amount(data.native_reward_sum, @coin, digits: 5, ellipsize: false, symbol: false)
%>
<option value="<%= pool_staking_address %>" data-token-reward-sum="<%= token_reward_sum %>" data-native-reward-sum="<%= native_reward_sum %>" data-epochs="<%= data.epochs %>" data-gas-limit="<%= data.gas_estimate %>">
<%=
BlockScoutWeb.AddressView.trimmed_hash(pool_staking_address) <>
" (" <>
token_reward_sum <> " " <> @token.symbol <>
token_reward_sum_short <> " " <> @token.symbol <>
"; " <>
native_reward_sum <> " " <> @coin.symbol <>
native_reward_sum_short <> " " <> @coin.symbol <>
")"
%>
</option>
@ -36,13 +38,13 @@
</p>
<input type="text" class="form-control specified-epochs hidden" placeholder='<%= gettext("Epochs range(s) or enum, e.g.: 5-9,23-27,47,50") %>' />
</div>
<div class="clearfix form-group">
<p class="form-p left">
<div class="form-group amounts">
<p class="form-p" align="left">
<%= gettext("You will receive:") %><br />
<span class="text-dark" id="token-reward-sum"></span> <span class="text-dark"><%= @token.symbol %></span><br />
<span class="text-dark" id="native-reward-sum"></span> <span class="text-dark"><%= @coin.symbol %></span><br />
</p>
<p class="form-p right">
<p class="form-p" align="right">
<%= gettext("Tx Gas Limit:") %><br />
<span class="text-dark" id="tx-gas-limit"></span><br />
</p>

Loading…
Cancel
Save