toast rework + fix bugs

This commit is contained in:
EmberSpirit
2023-10-04 17:20:21 +02:00
parent 3d53d9e7c8
commit 64d46693ea
24 changed files with 713 additions and 1464 deletions
+2
View File
@@ -6,6 +6,7 @@
src="/assets/img/blood-arrow-left.png"
alt="left-arrow"
@click="swiperInstance.slidePrev()"
v-if="token.length > 3"
/>
</div>
<swiper
@@ -80,6 +81,7 @@
src="/assets/img/blood-arrow-right.png"
alt="left-arrow"
@click="swiperInstance.slideNext()"
v-if="token.length > 3"
/>
</div>
</div>
+144 -5
View File
@@ -12,7 +12,13 @@
<template v-if="walletStore.memeToken?.unclaimedRewards > 0">
<Transition name="smooth">
<div class="connected-stake-buttons" v-show="!stakeMenu">
<div class="btn btn-immortal mid-mid-text" @click="rewardLockerStore.claimAll">Claim</div>
<div class="btn btn-immortal mid-mid-text" @click="claimAll" v-if="stateStake === 0">Claim</div>
<div class="btn btn-immortal mid-mid-text" disabled v-else-if="stateStake === 2">
Sign Transaction
</div>
<div class="btn btn-immortal stake-button" disabled v-else-if="stateStake === 3">
<loading-component></loading-component>
</div>
<div class="btn btn-immortal mid-mid-text" @click="openStake">Stake</div>
</div>
</Transition>
@@ -25,9 +31,22 @@
v-if="stakeMenu"
>
<template v-slot:body>
<div class="btn btn-immortal stake-button" @click="stakeAndClaimAllRounds">
<div class="btn btn-immortal stake-button" disabled v-if="stateClaimComp === 0">
Enter Amount
</div>
<div
class="btn btn-immortal stake-button"
v-else-if="stateClaimComp === 1"
@click="stakeAndClaimAllRounds"
>
Stake & Claim Rest
</div>
<div class="btn btn-immortal stake-button" disabled v-if="stateClaimComp === 2">
Sign Transaction
</div>
<div class="btn btn-immortal stake-button" disabled v-if="stateClaimComp === 3">
<loading-component></loading-component>
</div>
<div
class="btn transparent small-text cancel-button text-center"
@click="stakeMenu = false"
@@ -35,6 +54,9 @@
Cancel
</div>
</template>
<template v-slot:message-end>
<div class="input-balance">Balance: {{ walletStore.memeToken?.unclaimedRewards }}</div>
</template>
</stake-menu>
</Transition>
<div class="connected-stake-first-round small-text text-center">
@@ -52,17 +74,22 @@
</template>
<script setup>
import { ref } from "vue";
import { ref, computed } from "vue";
import CardComponent from "@/components/CardComponent.vue";
import StakeMenu from "@/components/StakeMenu.vue";
import TokenNamePrice from "@/components/TokenNamePrice.vue";
import TokenLogo from "@/components/TokenLogo.vue";
import { waitForTransaction } from "@wagmi/core";
import LoadingComponent from "@/components/LoadingComponent.vue";
import StakeSuccessToast from "@/components/toasts/StakeSuccessToast.vue";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { useTokenStore } from "@/stores/tokens";
import { useRewardLockerStore } from "@/stores/rewardlocker";
import { useRouter } from "vue-router";
import { useToast } from "vue-toastification";
const toast = useToast();
const rewardLockerStore = useRewardLockerStore();
const walletStore = useWalletStoreV2();
const tokenStore = useTokenStore();
@@ -79,6 +106,15 @@ const props = defineProps({
const stakeMenu = ref(false);
const stake = ref(null);
const tokenNumber = ref(null);
/**
* state 0 enter amount
* state 1 rdy to go
* state 2 signing
* state 3 loading
* state 4 staked
*/
const state = ref(0);
const stateClaim = ref(0);
function openStake() {
stake.value = true;
@@ -91,9 +127,112 @@ function openUnstake() {
}
async function stakeAndClaimAllRounds() {
try {
stateClaim.value = 2;
console.log("tokenNumber.value", tokenNumber.value);
console.log("walletStore.memeToken?.unclaimedRewards", walletStore.memeToken?.unclaimedRewards);
const coefficient = (10000 * tokenNumber.value) / walletStore.memeToken?.unclaimedRewards;
var hash = await rewardLockerStore.stakeAndClaimAllRounds(coefficient);
stateClaim.value = 3;
const data = await waitForTransaction({
hash: hash,
});
stateClaim.value = 4;
await walletStore.loadWalletData();
showSuccessToast(
walletStore.memeToken?.unclaimedRewards,
"Success!",
"You just claimed and staked",
"Join the next cycle to increase your rewards and win with your clan"
);
} catch (error) {
stateClaim.value = 0;
console.error(error);
throw new Error(error);
}
}
async function claimAll() {
try {
state.value = 2;
const hash = await rewardLockerStore.claimAll();
state.value = 3;
const data = await waitForTransaction({
hash: hash,
});
console.log("data", data);
await walletStore.loadWalletData();
showSuccessToast(
walletStore.memeToken?.unclaimedRewards,
"Success!",
"You just claimed",
"Join the next cycle to increase your rewards and win with your clan."
);
} catch (error) {
state.value = 0;
console.error(error);
throw new Error(error);
}
}
const stateStake = computed(() => {
let returnState = 0;
if (state.value === 2) {
returnState = 2;
} else if (state.value === 3) {
returnState = 3;
}
return returnState;
});
const stateClaimComp = computed(() => {
let returnState = 0;
console.log("tokenNumber.value", tokenNumber.value);
const coefficient = (10000 * tokenNumber.value) / walletStore.memeToken?.unclaimedRewards;
var result = await rewardLockerStore.stakeAndClaimAllRounds(coefficient);
if (
tokenNumber.value === null ||
tokenNumber.value === "" ||
tokenNumber.value === 0 ||
tokenNumber.value > walletStore.memeToken?.unclaimedRewards
) {
returnState = 0;
} else if (stateClaim.value === 2) {
returnState = 2;
} else if (stateClaim.value === 3) {
returnState = 3;
} else if (tokenNumber.value !== null || tokenNumber.value !== "" || tokenNumber.value > 0) {
returnState = 1;
}
return returnState;
});
function showSuccessToast(value, header, subheader, info) {
// Define the content object with the component, props and listeners
const content = {
component: StakeSuccessToast,
// Any prop can be passed, but don't expect them to be reactive
props: {
// counter: this.counter,
// value: tokenStore.activeToken.rewards?.toFixed(5),
value: value,
header: header,
subheader: subheader,
info: info,
},
// Listen and react to events using callbacks. In this case we listen for
// the "click" event emitted when clicking the toast button
listeners: {},
};
// Render the toast and its contents
toast(content, {
position: "top-center",
icon: false,
closeOnClick: false,
toastClassName: "modal-overlay",
closeButton: false,
hideProgressBar: true,
timeout: false,
});
}
</script>
+10 -2
View File
@@ -100,8 +100,16 @@ function badgeClick(token) {
var tokenData = tokenStore.getToken(token.contractAddress);
tokenStore.activeToken = tokenData;
// router.push({ name: "home", hash: `#${tokenData.name}` });
router.push({ name: "home" });
instance.parent.emit("update:modelValue", false);
if (tokenStore.memeToken.contractAddress === token.contractAddress) {
//buy
window.open(
"https://app.uniswap.org/swap?inputCurrency=ETH&outputCurrency=0x00E5DAd5dA0FC4Da0baB7f0D99E28C07d8A88ee4&chain=goerli",
"_blank"
);
} else {
router.push({ name: "home" });
instance.parent.emit("update:modelValue", false);
}
}
async function connectWallet(connector) {
+60 -11
View File
@@ -68,7 +68,7 @@
<div class="sacrifice-to-output-rewards header">{{ output.toFixed(5) }}</div>
</div>
<div class="sacrifice-logo">
<img :src="activeToken.vamp?.logo" :alt="activeToken.vamp.name" />
<img :src="activeToken.vamp?.logo" :alt="activeToken.vamp?.name" />
</div>
</div>
<div class="sacrifice-staking-bonus">
@@ -90,7 +90,7 @@
</stake-component-v1>
</div>
</div>
<div class="sacrificed-info" v-if="state === 4">
<div class="sacrificed-info" v-if="stateComputed === 4">
<div class="left low-mid-text">You can claim your $BLOOD when the cycle is finished.</div>
<div class="right">
<img src="/assets/img/moon.png" alt="moon" />
@@ -109,14 +109,15 @@
</div>
</div>
<div class="sacrifice-buttons-function-wrapper">
{{ stateComputed }}
<template v-if="walletStore.connected">
<div class="btn btn-immortal sub-header" disabled v-if="state === 0">Enter Amount</div>
<div class="btn btn-immortal sub-header" disabled v-if="stateComputed === 0">Enter Amount</div>
<div
class="btn btn-immortal sub-header"
v-if="
activeToken.allowance > 0 &&
activeToken.allowance >= tokenNumber &&
(state === 1 || state === 4)
(stateComputed === 1 || stateComputed === 4)
"
@click="sacrificeToken(tokenNumber)"
>
@@ -126,14 +127,14 @@
class="btn btn-immortal sub-header"
v-if="
(!activeToken.allowance || activeToken.allowance < tokenNumber) &&
(state === 1 || state === 4)
(stateComputed === 1 || stateComputed === 4)
"
@click="approveToken(tokenNumber)"
>
Approve Token
</div>
<div class="btn btn-immortal sub-header" disabled v-if="state === 2">Sign Transaction</div>
<div class="btn btn-immortal sub-header" disabled v-if="state === 3">
<div class="btn btn-immortal sub-header" disabled v-if="stateComputed === 2">Sign Transaction</div>
<div class="btn btn-immortal sub-header" disabled v-if="stateComputed === 3">
<loading-component></loading-component>
</div>
</template>
@@ -154,14 +155,16 @@ import { useUniswapStore } from "@/stores/uniswap";
import StakeComponentV1 from "@/components/StakeComponentV1.vue";
import LoadingComponent from "@/components/LoadingComponent.vue";
import TokenInput from "@/components/TokenInput.vue";
import StakeSuccessToast from "@/components/toasts/StakeSuccessToast.vue";
import { useToast } from "vue-toastification";
const toast = useToast();
import { storeToRefs } from "pinia";
import { waitForTransaction, readContract, watchBlockNumber } from "@wagmi/core";
import Helper from "@/utils/helper.js";
const isMobile = inject("isMobile");
const showPanel = inject("showPanel");
const showModal = inject("showModal");
const walletStore = useWalletStoreV2();
// const { connected } = storeToRefs(walletStore);
@@ -199,6 +202,19 @@ const state = ref(0);
const showStakingMenu = ref(false);
const approvalData = ref(null);
const stateComputed = computed(() => {
let returnState = 0;
if (tokenNumber.value === null || tokenNumber.value === "" || tokenNumber.value === 0) {
returnState = 0;
} else if (state.value === 2) {
returnState = 2;
} else if (state.value === 3) {
returnState = 3;
} else if (tokenNumber.value !== null || tokenNumber.value !== "" || tokenNumber.value > 0) {
returnState = 1;
}
return returnState;
});
const processChange = Helper.debounce((value) => getRewardsFor(value));
onMounted(() => {
@@ -267,7 +283,12 @@ async function sacrificeToken(amount) {
console.log("data", data);
activeToken.value.allowance = await tokenStore.allowance();
state.value = 4;
showModal.value = true;
showSuccessToast(
tokenStore.activeToken.rewards?.toFixed(5),
"Success!",
"You turned your meme into:",
"You can claim once the current cycle is finished and your clan bonus was calculated."
);
} catch (error) {
state.value = 0;
console.error(error);
@@ -288,8 +309,6 @@ async function approveToken(amount) {
} catch (error) {
console.error(error);
throw new Error(error);
} finally {
state.value = 1;
}
}
@@ -385,6 +404,36 @@ async function addTokens(value) {
tokenNumber.value = Number(tokenNumber.value) + Number(value);
output.value = await getRewardsFor(tokenNumber.value).output;
}
function showSuccessToast(value, header, subheader, info) {
// Define the content object with the component, props and listeners
const content = {
component: StakeSuccessToast,
// Any prop can be passed, but don't expect them to be reactive
props: {
// counter: this.counter,
// value: tokenStore.activeToken.rewards?.toFixed(5),
value: value,
header: header,
subheader: subheader,
info: info,
},
// Listen and react to events using callbacks. In this case we listen for
// the "click" event emitted when clicking the toast button
listeners: {},
};
// Render the toast and its contents
toast(content, {
position: "top-center",
icon: false,
closeOnClick: false,
toastClassName: "modal-overlay",
closeButton: false,
hideProgressBar: true,
timeout: false,
});
}
</script>
<style lang="sass">
+95 -11
View File
@@ -35,7 +35,7 @@
:price="walletStore.memeToken?.staked"
></token-name-price>
<token-logo img="/assets/img/token/bloodline.png" :alt="'^y '"></token-logo>
<token-name-price class="stake-reward" name="Extra Reward" price="+20%"></token-name-price>
<token-name-price class="stake-reward" name="Extra Reward" price="+25%"></token-name-price>
</slot>
</div>
<slot name="actions">
@@ -55,15 +55,22 @@
v-model="tokenNumber"
@close="stakeMenu = false"
:stake="stake"
:amount="walletStore.memeToken.balanceOf"
v-if="stakeMenu & !unstakeMenu"
>
<template v-slot:body>
<div
class="btn btn-immortal stake-button"
@click="rewardLockerStore.stakeBloodline(tokenNumber)"
>
<div class="btn btn-immortal stake-button" disabled v-if="stateStake === 0">
Enter Amount
</div>
<div class="btn btn-immortal stake-button" v-else-if="stateStake === 1" @click="stakeToken">
Stake
</div>
<div class="btn btn-immortal stake-button" disabled v-if="stateStake === 2">
Sign Transaction
</div>
<div class="btn btn-immortal stake-button" disabled v-if="stateStake === 3">
<loading-component></loading-component>
</div>
<div
class="btn transparent small-text cancel-button text-center"
@click="stakeMenu = false"
@@ -71,6 +78,9 @@
Cancel
</div>
</template>
<template v-slot:message-end>
<div class="input-balance">Balance: {{ walletStore.memeToken.balanceOf }}</div>
</template>
</stake-menu>
<div class="unstake-menu" v-else-if="stakeMenu & unstakeMenu">
<div class="low-mid-text text-center">
@@ -90,11 +100,7 @@
</div>
</div>
</Transition>
<!-- todo v-if activeround -->
<div
class="connected-stake-first-round small-text text-center"
v-if="roundStore.currentRound === roundStore.activeRound"
>
<div class="connected-stake-first-round small-text text-center" v-if="roundStore.currentRound === 0">
No $BLOOD on the market. Staking is activated after the first cycle is finished.
</div>
<div class="connected-stake-claim-info low-mid-text text-center">
@@ -107,17 +113,22 @@
</template>
<script setup>
import { ref, useSlots } from "vue";
import { ref, useSlots, computed } from "vue";
import CardComponent from "@/components/CardComponent.vue";
import StakeSuccessToast from "@/components/toasts/StakeSuccessToast.vue";
import StakeMenu from "@/components/StakeMenu.vue";
import TokenNamePrice from "@/components/TokenNamePrice.vue";
import TokenLogo from "@/components/TokenLogo.vue";
import { waitForTransaction } from "@wagmi/core";
import LoadingComponent from "@/components/LoadingComponent.vue";
import { useRoundsStore } from "@/stores/rounds";
import { useRewardLockerStore } from "@/stores/rewardlocker";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { useTokenStore } from "@/stores/tokens";
import { useToast } from "vue-toastification";
const toast = useToast();
const walletStore = useWalletStoreV2();
const tokenStore = useTokenStore();
const rewardLockerStore = useRewardLockerStore();
@@ -142,6 +153,15 @@ const stake = ref(null);
const tokenNumber = ref(null);
const loading = ref(false);
/**
* state 0 enter amount
* state 1 rdy to go
* state 2 signing
* state 3 loading
* state 4 staked
*/
const state = ref(0);
function openStake() {
stake.value = true;
unstakeMenu.value = false;
@@ -160,6 +180,70 @@ async function orderUnstake() {
console.log("orderUnstake", result);
loading.value = false;
}
async function stakeToken() {
try {
state.value = 2;
const hash = await rewardLockerStore.stakeBloodline(tokenNumber.value);
state.value = 3;
const data = await waitForTransaction({
hash: hash,
});
console.log("data", data);
state.value = 4;
await walletStore.loadWalletData();
showSuccessToast();
//reload data
} catch (error) {
state.value = 0;
console.error(error);
throw new Error(error);
}
}
const stateStake = computed(() => {
let returnState = 0;
if (tokenNumber.value === null || tokenNumber.value === "" || tokenNumber.value === 0) {
returnState = 0;
} else if (state.value === 2) {
returnState = 2;
} else if (state.value === 3) {
returnState = 3;
} else if (tokenNumber.value !== null || tokenNumber.value !== "" || tokenNumber.value > 0) {
returnState = 1;
}
return returnState;
});
function showSuccessToast() {
// Define the content object with the component, props and listeners
const content = {
component: StakeSuccessToast,
// Any prop can be passed, but don't expect them to be reactive
props: {
// counter: this.counter,
// value: tokenStore.activeToken.rewards?.toFixed(5),
value: tokenNumber.value,
header: "Success!",
subheader: "You just staked",
info: "Your next sacrifice will get an extra staking bonus as a reward.",
},
// Listen and react to events using callbacks. In this case we listen for
// the "click" event emitted when clicking the toast button
listeners: {},
};
// Render the toast and its contents
toast(content, {
position: "top-center",
icon: false,
closeOnClick: false,
toastClassName: "modal-overlay",
closeButton: false,
hideProgressBar: true,
timeout: false,
});
}
</script>
<style lang="sass">
+4 -1
View File
@@ -7,6 +7,9 @@
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(75)">75%</div>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(100)">100%</div>
</template>
<template v-slot:message-end>
<slot name="message-end"> </slot>
</template>
</token-input>
<div class="stake-menu-actions">
<slot name="body">
@@ -105,8 +108,8 @@ async function stakeBloodline() {
font-size: 18px
text-align: center
.input-balance
margin: 8px 0
color: var(--grey, #858585)
margin-left: auto
.stake-menu
display: flex
+39 -7
View File
@@ -46,7 +46,7 @@
<div class="rewards-body">
<div class="rewards-coin low-mid-text">$BLOOD</div>
<div class="rewards-amount header" v-if="activeRound === currentRound">0</div>
<div class="rewards-amount header" v-else>{{ getCurrentRoundData?.rewards_total }}</div>
<div class="rewards-amount header" v-else>{{ getCurrentRoundData?.rewards_total.toFixed(5) }}</div>
</div>
<img class="bloodline-token" src="/assets/img/token/bloodline.png" alt="vampir" />
</div>
@@ -71,7 +71,11 @@
<template v-else-if="getCurrentRoundData?.rewards_total > 0">
<Transition name="smooth">
<div class="stake-buttons" v-show="!stakeMenu">
<div class="btn btn-immortal" @click="claimRewards">Claim</div>
<div class="btn btn-immortal" v-if="stateClaimedComp === 0" @click="claimRewards">Claim</div>
<div class="btn btn-immortal" disabled v-if="stateClaimedComp === 2">Sign Transaction</div>
<div class="btn btn-immortal" disabled v-if="stateClaimedComp === 3">
<loading-component></loading-component>
</div>
<div class="btn btn-immortal" @click="openStake">Stake</div>
</div>
</Transition>
@@ -105,12 +109,14 @@
<script setup>
import { storeToRefs } from "pinia";
import RewardsWrapper from "@/components/RewardsWrapper.vue";
import { inject, ref, onMounted } from "vue";
import { inject, ref, onMounted, computed } from "vue";
import { useRewardLockerStore } from "@/stores/rewardlocker";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { useRoundsStore } from "@/stores/rounds";
import { useRouter } from "vue-router";
import StakeMenu from "@/components/StakeMenu.vue";
import { waitForTransaction } from "@wagmi/core";
import LoadingComponent from "@/components/LoadingComponent.vue";
const clanRewards = ref(0);
const rewards = ref(0);
@@ -127,6 +133,7 @@ const { activeRound, currentRound, getCurrentRoundData } = storeToRefs(roundStor
const stakeMenu = ref(false);
const stake = ref(null);
const tokenNumber = ref(null);
const stateClaim = ref(0);
async function stakeAndClaim() {
console.log(tokenNumber.value);
@@ -143,11 +150,36 @@ function openStake() {
onMounted(async () => {});
async function claimRewards() {
console.log("getCurrentRoundData", getCurrentRoundData);
console.log("activeRound.value", activeRound.value);
var result = await rewardLockerStore.claim([activeRound.value]);
console.log("result", result);
try {
stateClaim.value = 2;
console.log("getCurrentRoundData", getCurrentRoundData);
console.log("activeRound.value", activeRound.value);
var hash = await rewardLockerStore.claim([activeRound.value]);
stateClaim.value = 3;
console.log("hash", hash);
const data = await waitForTransaction({
hash: hash,
});
stateClaim.value = 4;
//reload
await roundStore.fillRound(activeRound.value, true);
await walletStore.loadWalletData();
} catch (error) {
stateClaim.value = 0;
console.error(error);
throw new Error(error);
}
}
const stateClaimedComp = computed(() => {
let returnState = 0;
if (stateClaim.value === 2) {
returnState = 2;
} else if (stateClaim.value === 3) {
returnState = 3;
}
return returnState;
});
</script>
<style lang="sass">
+1
View File
@@ -9,6 +9,7 @@
<div class="value-adder">
<slot class="value-adder" name="message"></slot>
<slot name="message-end"></slot>
</div>
</div>
</template>
+102
View File
@@ -0,0 +1,102 @@
<template>
<card-component class="modal-card">
<div class="body">
<div class="header">
<img alt="logo" class="logo" src="/assets/img/vampir.png" />
</div>
<div class="subheader toast-header">
{{ props.header }}<br />
{{ props.subheader }}
</div>
<div class="amount-number">
<div class="token-amount number-mobile">{{ props.value }}</div>
<div class="token-name">$Blood</div>
</div>
<div class="info toast-body">
{{ props.info }}
</div>
</div>
<div class="btn btn-immortal" @click="closeToast">Okay</div>
</card-component>
</template>
<script setup>
import { getCurrentInstance } from "vue";
import CardComponent from "@/components/CardComponent.vue";
import { useToast } from "vue-toastification";
const props = defineProps({
value: String,
header: String,
subheader: String,
info: String,
});
// element.classList.add("toast-open");
const toast = useToast();
const instance = getCurrentInstance();
instance.parent.parent.vnode.el.classList.add("toast-open");
const id = instance.attrs["toast-id"];
function closeToast() {
instance.parent.parent.vnode.el.classList.remove("toast-open");
toast.dismiss(id);
}
console.log("instance", instance.attrs["toast-id"]);
</script>
<style lang="sass">
.Vue-Toastification__container
&.toast-open
background-color: rgb(15, 15, 15, 0.7)
height: 100vh
width: 100vw
position: fixed
left: 0
bottom: 0
z-index: 10
@media (min-width: 992px)
background-color: unset
&.top-center
@media (min-width: 600px)
left: unset
margin-left: unset
.Vue-Toastification__toast
max-width: unset
min-width: unset
max-height: unset
min-height: unset
font-family: unset
margin-bottom: unset
box-shadow: unset
padding: unset
&.modal-overlay
background-color: unset
.modal-card
width: 342px
text-align: center
position: absolute
top: 50%
left: 50%
transform: translate(-50%, -50%)
border: 2px solid var(--dark-purple, #4B0082)
background: var(--midnight-black, #0F0F0F)
z-index: 100
gap: 16px
@media (min-width: 992px)
top: 142px
right: 24px
left: unset
transform: unset
.body
display: flex
flex-direction: column
gap: 8px
.amount-number
display: flex
justify-content: center
align-items: end
gap: 8px
img
width: 74px
height: 74px
</style>