Skip to content

Commit

Permalink
πŸš€ [Frontend] Swap UI improvements πŸš€ (#580)
Browse files Browse the repository at this point in the history
* Improve loaders

* Throw if transaction rejected

* Show swap details in the confirmation screen, show failed popup if transaction rejected, ui improvements

* Add slippage panel, improve swap UI, add assets

* Add core functionality to handle min_receiving_amount

* Fix swap test

* Disallow negative slippage

* Disable swaps if input or output is more than pool balances

* Add backend changes

* Fix clp and clp service

* Split failed/rejected states & dialogs, handle min swap amount in UI, refactoring

* Fix test

* Add todo

* Add TODO

* Add TODO

* Fix broken tests

Co-authored-by: 59023g <m.edward.pierce@gmail.com>
Co-authored-by: Rudi Yardley <contact@rudiyardley.com>
  • Loading branch information
3 people committed Jan 28, 2021
1 parent 5abb741 commit 146b572
Show file tree
Hide file tree
Showing 25 changed files with 425 additions and 99 deletions.
13 changes: 12 additions & 1 deletion ui/app/src/App.vue
Expand Up @@ -50,11 +50,22 @@ export default defineComponent({
text-align: center;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type=number] {
-moz-appearance: textfield;
}
a {
font-weight: bold;
}
.main {
min-height: 100vh;
}
</style>
</style>
35 changes: 31 additions & 4 deletions ui/app/src/components/confirmationDialog/AnimatedConfirmation.vue
Expand Up @@ -2,7 +2,7 @@
<div>
<div class="confirmation">
<div class="message">
<Loader black :success="confirmed" /><br />
<Loader black :success="confirmed" :failed="failed" /><br />
<div class="text-wrapper">
<transition name="swipe">
<div class="text" v-if="state === 'signing'">
Expand All @@ -17,11 +17,37 @@
<p class="sub">Confirm this transaction in your wallet</p>
</div>
</transition>
<transition name="swipe">
<div class="text" v-if="state === 'rejected'">
<p>Transaction Rejected</p>
<p class="thin">
Failed to swap
<span class="thick">{{ _fromAmount }} {{ _fromToken }}</span>
for
<span class="thick">{{ _toAmount }} {{ _toToken }}</span>
</p>
<br />
<p class="sub">Please confirm the transaction in your wallet.</p>
</div>
</transition>
<transition name="swipe">
<div class="text" v-if="state === 'failed'">
<p>Transaction Failed</p>
<p class="thin">
Failed to swap
<span class="thick">{{ _fromAmount }} {{ _fromToken }}</span>
for
<span class="thick">{{ _toAmount }} {{ _toToken }}</span>
</p>
<br />
<p class="sub">Please try to increase slippage tolerance.</p>
</div>
</transition>
<transition name="swipe">
<div class="text" v-if="confirmed">
<p>Transaction Submitted</p>
<p class="thin">
Swapping
Swapped
<span class="thick">{{ _fromAmount }} {{ _fromToken }}</span>
for
<span class="thick">{{ _toAmount }} {{ _toToken }}</span>
Expand Down Expand Up @@ -55,6 +81,7 @@ export default defineComponent({
components: { Loader, SifButton },
props: {
confirmed: Boolean,
failed: Boolean,
state: String,
fromAmount: String,
fromToken: String,
Expand All @@ -64,7 +91,7 @@ export default defineComponent({
},
setup(props) {
const { config } = useCore();
// Need to cache amounts and disconnect reactivity
return {
_fromAmount: props.fromAmount,
Expand Down Expand Up @@ -133,4 +160,4 @@ export default defineComponent({
.swipe-leave-to {
transform: translateX(-100%);
}
</style>
</style>
6 changes: 3 additions & 3 deletions ui/app/src/components/confirmationDialog/AskConfirmation.vue
Expand Up @@ -47,9 +47,9 @@ export default defineComponent({
:providerFee="providerFee"
:priceImpact="priceImpact"
/>
<SifButton block primary class="confirm-btn" @click="$emit('confirmswap')"
>Confirm Swap</SifButton
>
<SifButton block primary class="confirm-btn" @click="$emit('confirmswap')">
Confirm Swap
</SifButton>
</div>
</template>

Expand Down
Expand Up @@ -10,6 +10,7 @@ export type ConfirmState =
| "confirming"
| "signing"
| "confirmed"
| "rejected"
| "failed";
export default defineComponent({
Expand All @@ -34,8 +35,13 @@ export default defineComponent({
return props.state === "confirmed";
});
const failed = computed(() => {
return props.state === "failed" || props.state === "rejected";
});
return {
confirmed,
failed
};
},
});
Expand All @@ -58,6 +64,7 @@ export default defineComponent({
<AnimatedConfirmation
v-else
:confirmed="confirmed"
:failed="failed"
:state="state"
:fromAmount="fromAmount"
:fromToken="fromToken"
Expand Down
Expand Up @@ -11,6 +11,7 @@ export type ConfirmState =
| "confirming"
| "signing"
| "confirmed"
| "rejected"
| "failed";
export default defineComponent({
Expand Down
Expand Up @@ -10,6 +10,7 @@ export type ConfirmState =
| "confirming"
| "signing"
| "confirmed"
| "rejected"
| "failed";
export default defineComponent({
Expand Down
34 changes: 29 additions & 5 deletions ui/app/src/components/shared/DetailsPanel.vue
Expand Up @@ -13,16 +13,16 @@
class="details-body"
>
<div v-if="minimumReceived && toToken" class="details-row">
<span>Expected Amount Received</span>
<span>{{ minimumReceived }} {{ toToken }}</span>
<span>Minimum Amount Received</span>
<span>{{ minimumReceived }} <span>{{ toToken.toUpperCase().replace("C", "c") }}</span></span>
</div>
<div v-if="priceImpact" class="details-row">
<span>Price Impact</span>
<span>{{ priceImpact }}%</span>
<span>{{ parseFloat(priceImpact) < 0.01 ? "< 0.01" : parseFloat(priceImpact).toFixed(2) }} %</span>
</div>
<div v-if="providerFee && toToken" class="details-row">
<span>Liquidity Provider Fee</span>
<span>{{ providerFee }} {{ toToken }}</span>
<span>{{ showProviderFee(providerFee) }} <span>{{ toToken.toUpperCase().replace("C", "c") }}</span></span>
</div>
</div>
</div>
Expand All @@ -49,6 +49,11 @@
span:last-child {
text-align: right;
color: $c_gray_900;
span {
color: $c_gold_dark;
font-weight: 700;
}
}
span:first-child {
Expand All @@ -61,7 +66,6 @@
</style>
<script lang="ts">
import { defineComponent } from "vue";
import { computed } from "@vue/reactivity";
export default defineComponent({
props: {
Expand All @@ -71,5 +75,25 @@ export default defineComponent({
providerFee: { type: String, default: "" },
priceImpact: { type: String, default: "" },
},
setup() {
function showProviderFee(providerFee: string) {
const floatFee = parseFloat(providerFee);
if (floatFee < 0.001) {
return providerFee;
} else if (floatFee < 10) {
return floatFee.toFixed(4)
} else if (floatFee < 100) {
return floatFee.toFixed(3)
} else if (floatFee < 1000) {
return floatFee.toFixed(2)
} else {
return floatFee.toFixed(1)
}
}
return {
showProviderFee
}
}
});
</script>
11 changes: 8 additions & 3 deletions ui/app/src/components/shared/Loader.vue
@@ -1,10 +1,13 @@
<template>
<div class="positioner">
<LoaderCircle :black="black" :success="success" />
<LoaderCircle :black="black" :success="success || failed" />
<div class="tick-holder">
<transition name="reveal">
<LoaderTick v-if="success" class="tick" />
</transition>
<transition name="reveal">
<LoaderFailed v-if="failed" class="tick" />
</transition>
</div>
</div>
</template>
Expand All @@ -13,12 +16,14 @@
import { defineComponent } from "vue";
import LoaderTick from "@/components/shared/LoaderTick.vue";
import LoaderCircle from "@/components/shared/LoaderCircle.vue";
import LoaderFailed from "@/components/shared/LoaderFailed.vue";
export default defineComponent({
components: { LoaderCircle, LoaderTick },
components: { LoaderCircle, LoaderTick, LoaderFailed },
props: {
black: { type: Boolean, default: false },
success: { type: Boolean, default: false },
failed: { type: Boolean, default: false },
},
});
</script>
Expand Down Expand Up @@ -55,4 +60,4 @@ export default defineComponent({
.reveal-enter-from {
max-width: 0;
}
</style>
</style>
8 changes: 4 additions & 4 deletions ui/app/src/components/shared/LoaderCircle.vue
Expand Up @@ -38,10 +38,10 @@ export default defineComponent({
animation: load8 1.1s infinite linear;
&.success {
animation: none;
border-top: 2px solid $c_gray_700;
border-right: 2px solid $c_gray_700;
border-bottom: 2px solid $c_gray_700;
border-left: 2px solid $c_gray_700;
border-top: 0;
border-right: 0;
border-bottom: 0;
border-left: 0;
}
}
Expand Down
25 changes: 25 additions & 0 deletions ui/app/src/components/shared/LoaderFailed.vue
@@ -0,0 +1,25 @@
<template>
<div class="tickwrap">
<svg xmlns="http://www.w3.org/2000/svg" width="66" height="66" viewBox="0 0 66 66">
<g id="Gruppe_1920" data-name="Gruppe 1920" transform="translate(-925 -447)">
<g id="Gruppe_1669" data-name="Gruppe 1669" transform="translate(-2.206 -21.301)">
<g id="Gruppe_1445" data-name="Gruppe 1445" transform="translate(948.206 489.301)">
<line id="Linie_13" data-name="Linie 13" x2="24.494" y2="24.494" fill="none" stroke="#b51a1a" stroke-linecap="round" stroke-width="2"/>
<line id="Linie_14" data-name="Linie 14" x2="24.494" y2="24.494" transform="translate(24.494) rotate(90)" fill="none" stroke="#b51a1a" stroke-linecap="round" stroke-width="2"/>
</g>
</g>
<g id="Ellipse_48" data-name="Ellipse 48" transform="translate(925 447)" fill="none" stroke="#b51a1a" stroke-width="2">
<circle cx="33" cy="33" r="33" stroke="none"/>
<circle cx="33" cy="33" r="32" fill="none"/>
</g>
</g>
</svg>
</div>
</template>
<style scoped>
.tickwrap {
display: block;
width: 66px;
height: 66px;
}
</style>
30 changes: 8 additions & 22 deletions ui/app/src/components/shared/LoaderTick.vue
@@ -1,26 +1,12 @@
<template>
<div class="tickwrap">
<svg
xmlns="http://www.w3.org/2000/svg"
width="66"
height="66"
viewBox="0 0 66 66"
>
<g
id="Gruppe_1454"
data-name="Gruppe 1454"
transform="translate(-925 -375)"
>
<path
id="Pfad_1933"
data-name="Pfad 1933"
d="M1253.021,457.91l10.233,10.234,19.254-19.253"
transform="translate(-307.477 -50.512)"
fill="none"
stroke-linecap="round"
stroke-miterlimit="10"
stroke-width="2"
/>
<svg xmlns="http://www.w3.org/2000/svg" width="66" height="66" viewBox="0 0 66 66">
<g id="Gruppe_1454" data-name="Gruppe 1454" transform="translate(-925 -375)">
<g id="Ellipse_34" data-name="Ellipse 34" transform="translate(925 375)" fill="none" stroke="#8cc63f" stroke-width="2">
<circle cx="33" cy="33" r="33" stroke="none"/>
<circle cx="33" cy="33" r="32" fill="none"/>
</g>
<path id="Pfad_1933" data-name="Pfad 1933" d="M1253.021,457.91l10.233,10.234,19.254-19.253" transform="translate(-307.477 -50.512)" fill="none" stroke="#8cc63f" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2"/>
</g>
</svg>
</div>
Expand All @@ -31,4 +17,4 @@
width: 66px;
height: 66px;
}
</style>
</style>

1 comment on commit 146b572

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for ui ready!

βœ… Preview
https://ui-9qldr2rty.vercel.app
https://develop.sifchain.vercel.app

Built with commit 146b572.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.