From 43fab6960d6fae39bac902ad25bf914d2cfc9452 Mon Sep 17 00:00:00 2001 From: Mraveux Date: Mon, 15 Jul 2024 12:32:35 +0200 Subject: [PATCH 1/7] AmountSlider: Allow to reduce staked amount remove some code ported from prestaking that prevented the amount from being lowered below the already staked amount. (since that is not possible during prestaking, but is possible with staking) --- src/components/staking/AmountSlider.vue | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/staking/AmountSlider.vue b/src/components/staking/AmountSlider.vue index 424d6d701..0d43ed5de 100644 --- a/src/components/staking/AmountSlider.vue +++ b/src/components/staking/AmountSlider.vue @@ -233,8 +233,8 @@ export default defineComponent({ await context.root.$nextTick(); } - // Ensure the entered amount does not fall below the minimum stake or already staked amount - valueNim = Math.max(valueNim, MIN_STAKE, alreadyStakedAmount.value); + // Ensure the entered amount does not fall below the minimum stake + valueNim = Math.max(valueNim, MIN_STAKE); const amount = Math.max( 0, Math.min(availableAmount.value, valueNim), @@ -303,7 +303,7 @@ export default defineComponent({ (100 * (position.x - pivotPoint.x - sliderBox.x)) / (sliderBox.width - knobBox.width), )); // Ensure the slider does not go below the minimum stake percentage - percent = Math.max(minimumStakePercent.value, alreadyStakedPercentage.value, percent); + percent = Math.max(minimumStakePercent.value, percent); const offsetX = getPointAtPercent(percent); let newAmount; @@ -314,8 +314,8 @@ export default defineComponent({ } else { // Calculate new amount from slider's position, ensuring it's not below minimum prestake newAmount = Math.floor(((percent / 100) * availableAmount.value) / 1e5) * 1e5; - // Prevent reducing below MIN_STAKE or already staked amount - newAmount = Math.max(newAmount, MIN_STAKE, alreadyStakedAmount.value); + // Prevent reducing below MIN_STAKE + newAmount = Math.max(newAmount, MIN_STAKE); } currentAmount.value = newAmount; From 30888788d3013137ab149b94a2e44bcc5b6c2b14 Mon Sep 17 00:00:00 2001 From: Mraveux Date: Mon, 15 Jul 2024 14:40:19 +0200 Subject: [PATCH 2/7] StakingInfoPage: comment out "Unstaking all" and "Deactivate all", for new UI designs. --- src/components/staking/StakingInfoPage.vue | 302 ++++++++++----------- 1 file changed, 151 insertions(+), 151 deletions(-) diff --git a/src/components/staking/StakingInfoPage.vue b/src/components/staking/StakingInfoPage.vue index 4b67f345c..cd3e6e980 100644 --- a/src/components/staking/StakingInfoPage.vue +++ b/src/components/staking/StakingInfoPage.vue @@ -69,25 +69,25 @@ {{ $t('You can\'t adjust your stake while you\'re unstaking') }} - + -->
 {{ $t('available to unstake') }} -
-
--> +
{{ $t('Deactivating') }}  @@ -98,14 +98,14 @@ class="unstaking row flex-row nq-light-blue" >  {{ $t('available to unstake') }} -
-
--> + @@ -235,146 +235,146 @@ export default defineComponent({ && (stake.value.inactiveRelease && stake.value.inactiveRelease < height.value), ); - async function unstakeAll(removeOnly = false) { - context.emit('statusChange', { - type: StatusChangeType.UNSTAKING, - state: State.LOADING, - title: context.root.$t('Sending Unstaking Transaction') as string, - }); - - try { - const { Address, TransactionBuilder } = await import('@nimiq/core'); - const client = await getNetworkClient(); - - const transactions = [ - ...(removeOnly ? [] : [ - TransactionBuilder.newRetireStake( - Address.fromUserFriendlyAddress(activeAddress.value!), - BigInt(stake.value!.inactiveBalance), - BigInt(0), - useNetworkStore().state.height, - await client.getNetworkId(), - ), - ]), - // It is only allowed to remove the complete retired balance, not only parts of it. - TransactionBuilder.newRemoveStake( - Address.fromUserFriendlyAddress(activeAddress.value!), - BigInt(removeOnly - ? stake.value!.retiredBalance - : stake.value!.retiredBalance + stake.value!.inactiveBalance), - BigInt(0), - useNetworkStore().state.height, - await client.getNetworkId(), - ), - ]; - - const unstakedAmount = removeOnly - ? stake.value!.retiredBalance - : stake.value!.retiredBalance + stake.value!.inactiveBalance; - - const txs = await sendStaking({ - transaction: transactions.map((tx) => tx.serialize()), - }); - - if (!txs) { - context.emit('statusChange', { - type: StatusChangeType.NONE, - }); - return; - } - - if (txs.some((tx) => tx.executionResult === false)) { - throw new Error('The transaction did not succeed'); - } - - context.emit('statusChange', { - state: State.SUCCESS, - title: context.root.$t('Successfully unstaked {amount} NIM', { amount: unstakedAmount / 1e5 }), - }); - - // // Close staking modal - // context.root.$router.back(); - context.emit('statusChange', { - type: StatusChangeType.NONE, - timeout: SUCCESS_REDIRECT_DELAY, - }); - } catch (error: any) { - if (config.reportToSentry) captureException(error); - else console.error(error); // eslint-disable-line no-console - - context.emit('statusChange', { - state: State.WARNING, - title: context.root.$t('Something went wrong') as string, - message: `${error.message} - ${error.data}`, - }); - } - } - - async function deactivateAll() { - context.emit('statusChange', { - type: StatusChangeType.DEACTIVATING, - state: State.LOADING, - title: context.root.$t('Sending Staking Transaction') as string, - }); - - const validatorLabelOrAddress = 'label' in validator.value! - ? validator.value.label : validator.value!.address; - - try { - const { Address, TransactionBuilder } = await import('@nimiq/core'); - const client = await getNetworkClient(); - - const transaction = TransactionBuilder.newSetActiveStake( - Address.fromUserFriendlyAddress(activeAddress.value!), - BigInt(0), - BigInt(0), - useNetworkStore().state.height, - await client.getNetworkId(), - ); - const txs = await sendStaking({ - transaction: transaction.serialize(), - }).catch((error) => { - throw new Error(error.data); - }); - - if (!txs) { - context.emit('statusChange', { - type: StatusChangeType.NONE, - }); - return; - } - - if (txs.some((tx) => tx.executionResult === false)) { - throw new Error('The transaction did not succeed'); - } - - context.emit('statusChange', { - state: State.SUCCESS, - title: context.root.$t( - 'Successfully deactivated {amount} NIM from your stake with {validator}', - { - amount: Math.abs(stake.value!.activeBalance / 1e5), - validator: validatorLabelOrAddress, - }, - ), - }); - - context.emit('statusChange', { - type: StatusChangeType.NONE, - timeout: SUCCESS_REDIRECT_DELAY, - }); - } catch (error: any) { - if (config.reportToSentry) captureException(error); - else console.error(error); // eslint-disable-line no-console - - // Show error screen - context.emit('statusChange', { - state: State.WARNING, - title: context.root.$t('Something went wrong') as string, - message: `${error.message} - ${error.data}`, - }); - } - } + // async function unstakeAll(removeOnly = false) { + // context.emit('statusChange', { + // type: StatusChangeType.UNSTAKING, + // state: State.LOADING, + // title: context.root.$t('Sending Unstaking Transaction') as string, + // }); + + // try { + // const { Address, TransactionBuilder } = await import('@nimiq/core'); + // const client = await getNetworkClient(); + + // const transactions = [ + // ...(removeOnly ? [] : [ + // TransactionBuilder.newRetireStake( + // Address.fromUserFriendlyAddress(activeAddress.value!), + // BigInt(stake.value!.inactiveBalance), + // BigInt(0), + // useNetworkStore().state.height, + // await client.getNetworkId(), + // ), + // ]), + // // It is only allowed to remove the complete retired balance, not only parts of it. + // TransactionBuilder.newRemoveStake( + // Address.fromUserFriendlyAddress(activeAddress.value!), + // BigInt(removeOnly + // ? stake.value!.retiredBalance + // : stake.value!.retiredBalance + stake.value!.inactiveBalance), + // BigInt(0), + // useNetworkStore().state.height, + // await client.getNetworkId(), + // ), + // ]; + + // const unstakedAmount = removeOnly + // ? stake.value!.retiredBalance + // : stake.value!.retiredBalance + stake.value!.inactiveBalance; + + // const txs = await sendStaking({ + // transaction: transactions.map((tx) => tx.serialize()), + // }); + + // if (!txs) { + // context.emit('statusChange', { + // type: StatusChangeType.NONE, + // }); + // return; + // } + + // if (txs.some((tx) => tx.executionResult === false)) { + // throw new Error('The transaction did not succeed'); + // } + + // context.emit('statusChange', { + // state: State.SUCCESS, + // title: context.root.$t('Successfully unstaked {amount} NIM', { amount: unstakedAmount / 1e5 }), + // }); + + // // // Close staking modal + // // context.root.$router.back(); + // context.emit('statusChange', { + // type: StatusChangeType.NONE, + // timeout: SUCCESS_REDIRECT_DELAY, + // }); + // } catch (error: any) { + // if (config.reportToSentry) captureException(error); + // else console.error(error); // eslint-disable-line no-console + + // context.emit('statusChange', { + // state: State.WARNING, + // title: context.root.$t('Something went wrong') as string, + // message: `${error.message} - ${error.data}`, + // }); + // } + // } + + // async function deactivateAll() { + // context.emit('statusChange', { + // type: StatusChangeType.DEACTIVATING, + // state: State.LOADING, + // title: context.root.$t('Sending Staking Transaction') as string, + // }); + + // const validatorLabelOrAddress = 'label' in validator.value! + // ? validator.value.label : validator.value!.address; + + // try { + // const { Address, TransactionBuilder } = await import('@nimiq/core'); + // const client = await getNetworkClient(); + + // const transaction = TransactionBuilder.newSetActiveStake( + // Address.fromUserFriendlyAddress(activeAddress.value!), + // BigInt(0), + // BigInt(0), + // useNetworkStore().state.height, + // await client.getNetworkId(), + // ); + // const txs = await sendStaking({ + // transaction: transaction.serialize(), + // }).catch((error) => { + // throw new Error(error.data); + // }); + + // if (!txs) { + // context.emit('statusChange', { + // type: StatusChangeType.NONE, + // }); + // return; + // } + + // if (txs.some((tx) => tx.executionResult === false)) { + // throw new Error('The transaction did not succeed'); + // } + + // context.emit('statusChange', { + // state: State.SUCCESS, + // title: context.root.$t( + // 'Successfully deactivated {amount} NIM from your stake with {validator}', + // { + // amount: Math.abs(stake.value!.activeBalance / 1e5), + // validator: validatorLabelOrAddress, + // }, + // ), + // }); + + // context.emit('statusChange', { + // type: StatusChangeType.NONE, + // timeout: SUCCESS_REDIRECT_DELAY, + // }); + // } catch (error: any) { + // if (config.reportToSentry) captureException(error); + // else console.error(error); // eslint-disable-line no-console + + // // Show error screen + // context.emit('statusChange', { + // state: State.WARNING, + // title: context.root.$t('Something went wrong') as string, + // message: `${error.message} - ${error.data}`, + // }); + // } + // } return { // NOW, @@ -387,8 +387,8 @@ export default defineComponent({ inactiveReleaseTime, hasUnstakableStake, isStakeDeactivating, - unstakeAll, - deactivateAll, + // unstakeAll, + // deactivateAll, canSwitchValidator, consensus, MIN_STAKE, @@ -475,7 +475,7 @@ export default defineComponent({ } .adjust-stake { - margin-right: 2rem; + // margin-right: 2rem; ::v-deep .tooltip-box { width: 25.75rem; } From f490c3ba18d598d138d8c65875b69cc812b275e4 Mon Sep 17 00:00:00 2001 From: Mraveux Date: Fri, 2 Aug 2024 14:29:41 +0200 Subject: [PATCH 3/7] Staking: allow to set amount slider to 0 to unstake all. --- src/components/staking/AmountSlider.vue | 27 +++++---------------- src/components/staking/StakingGraphPage.vue | 4 +-- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/src/components/staking/AmountSlider.vue b/src/components/staking/AmountSlider.vue index 0d43ed5de..0e66f202f 100644 --- a/src/components/staking/AmountSlider.vue +++ b/src/components/staking/AmountSlider.vue @@ -62,7 +62,6 @@ @@ -495,21 +433,62 @@ export default defineComponent({ } .unstaking { + flex-wrap: wrap; align-items: center; font-size: var(--body-size); font-weight: 600; margin-top: 2rem; - ::v-deep .circle-spinner { - margin-right: 1rem; - } + .nq-button-s, + .nq-button-pill { + display: flex; + flex-direction: row; + align-items: center; + color: white; - .inactive-release-timer { - box-shadow: 0 0 0 1.5px nimiq-light-blue(0.4); - border-radius: 5rem; - line-height: 1; - padding: 0.25rem 0.75rem; - font-size: var(--small-size); + &:first-child { + z-index: 2; + box-shadow: 0px 0px 0px 3px white; + cursor: default; + + .nq-icon { + margin-right: 0.75rem; + } + } + + &:nth-child(2) { + padding-left: 2rem; + margin-left: -0.4rem; + + --left-radius: 0px; + border-top-left-radius: var(--left-radius); + border-bottom-left-radius: var(--left-radius); + + .nq-icon { + margin-left: 0.75rem; + } + } + + &.unstaking-amount { background-color: #797B91 } + + &.unstaking-progress { + color: nimiq-blue(0.6); + + pointer-events: none; + cursor: default; + + span { + color: nimiq-blue(1); + margin-left: 1rem; + } + } + } + p { + color: nimiq-blue(0.6); + font-size: 1.5rem; + margin: 0; + margin-top: 1rem; + width: 100%; } } From 7fa84d89f85ce068dc50dff96def7b5534230b53 Mon Sep 17 00:00:00 2001 From: Mraveux Date: Mon, 12 Aug 2024 14:49:36 +0200 Subject: [PATCH 7/7] Update i18n source en.po file --- src/i18n/en.po | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/src/i18n/en.po b/src/i18n/en.po index ee18227aa..98c391183 100644 --- a/src/i18n/en.po +++ b/src/i18n/en.po @@ -375,11 +375,6 @@ msgstr "" msgid "Automatic mode uses {behavior}." msgstr "" -#: src/components/staking/StakingInfoPage.vue:100 -#: src/components/staking/StakingInfoPage.vue:81 -msgid "available to unstake" -msgstr "" - #: src/components/swap/SwapAnimation.vue:294 msgid "Awaiting swap secret" msgstr "" @@ -825,18 +820,10 @@ msgstr "" msgid "Credit Card" msgstr "" -#: src/components/staking/StakingInfoPage.vue:74 -msgid "Deactivate All" -msgstr "" - #: src/lib/StakingUtils.ts:55 msgid "Deactivate validator" msgstr "" -#: src/components/staking/StakingInfoPage.vue:93 -msgid "Deactivating" -msgstr "" - #: src/lib/StakingUtils.ts:28 msgid "Delete validator" msgstr "" @@ -1298,7 +1285,7 @@ msgstr "" msgid "In case of any issues, like exceeded limits or insufficient amounts, the automatic refunds will only work for individual IBAN addresses." msgstr "" -#: src/components/staking/StakingInfoPage.vue:204 +#: src/components/staking/StakingInfoPage.vue:208 msgid "Inactive validator" msgstr "" @@ -2040,7 +2027,6 @@ msgstr "" #: src/components/staking/StakingGraphPage.vue:139 #: src/components/staking/StakingGraphPage.vue:221 -#: src/components/staking/StakingInfoPage.vue:317 msgid "Sending Staking Transaction" msgstr "" @@ -2050,7 +2036,7 @@ msgstr "" msgid "Sending Transaction" msgstr "" -#: src/components/staking/StakingInfoPage.vue:242 +#: src/components/staking/StakingInfoPage.vue:246 msgid "Sending Unstaking Transaction" msgstr "" @@ -2196,8 +2182,7 @@ msgstr "" #: src/components/modals/SendModal.vue:826 #: src/components/modals/UsdcSendModal.vue:646 #: src/components/staking/StakingGraphPage.vue:276 -#: src/components/staking/StakingInfoPage.vue:307 -#: src/components/staking/StakingInfoPage.vue:373 +#: src/components/staking/StakingInfoPage.vue:311 #: src/components/staking/StakingValidatorPage.vue:154 msgid "Something went wrong" msgstr "" @@ -2281,7 +2266,6 @@ msgid "Successfully changed validator to {validator}" msgstr "" #: src/components/staking/StakingGraphPage.vue:250 -#: src/components/staking/StakingInfoPage.vue:353 msgid "Successfully deactivated {amount} NIM from your stake with {validator}" msgstr "" @@ -2289,7 +2273,7 @@ msgstr "" msgid "Successfully staked {amount} NIM with {validator}" msgstr "" -#: src/components/staking/StakingInfoPage.vue:292 +#: src/components/staking/StakingInfoPage.vue:296 msgid "Successfully unstaked {amount} NIM" msgstr "" @@ -2378,7 +2362,7 @@ msgstr "" msgid "Switch validator" msgstr "" -#: src/components/staking/StakingInfoPage.vue:142 +#: src/components/staking/StakingInfoPage.vue:145 msgid "Switch Validator" msgstr "" @@ -2660,7 +2644,7 @@ msgstr "" msgid "Unlock at any time. Your NIM will be available within hours." msgstr "" -#: src/components/staking/StakingInfoPage.vue:203 +#: src/components/staking/StakingInfoPage.vue:207 #: src/components/staking/ValidatorListItem.vue:53 msgid "Unregistered validator" msgstr "" @@ -2669,11 +2653,6 @@ msgstr "" msgid "Unstake" msgstr "" -#: src/components/staking/StakingInfoPage.vue:107 -#: src/components/staking/StakingInfoPage.vue:89 -msgid "Unstake All" -msgstr "" - #: src/swap-kyc-handler.ts:148 #: src/swap-kyc-handler.ts:157 msgid "Unsupported currency" @@ -2725,7 +2704,7 @@ msgstr "" msgid "Use the slider to lock your NIM and earn rewards." msgstr "" -#: src/components/staking/StakingInfoPage.vue:116 +#: src/components/staking/StakingInfoPage.vue:119 msgid "Validator" msgstr ""