update contracts+ desktop version

This commit is contained in:
EmberSpirit
2023-09-24 11:38:12 +02:00
parent 1b2ea9b2a2
commit 5c7053c0d9
40 changed files with 2327 additions and 2586 deletions
+40 -28
View File
@@ -1,5 +1,5 @@
<template>
<stake-component v-if="walletStore.memeToken?.unclaimedRewards > 0">
<stake-component>
<template v-slot:headline> Unclaimed </template>
<template v-slot:body>
<token-name-price
@@ -9,36 +9,46 @@
<token-logo img="/assets/img/token/bloodline.png" :alt="'bloodline logo'"></token-logo>
</template>
<template v-slot:actions>
<Transition name="smooth">
<div class="connected-stake-buttons" v-show="!stakeMenu">
<div class="btn btn-immortal" @click="rewardLockerStore.claimAll">Claim</div>
<div class="btn btn-immortal" @click="openStake">Stake</div>
<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="openStake">Stake</div>
</div>
</Transition>
<Transition name="smooth">
<stake-menu
v-model="tokenNumber"
@close="stakeMenu = false"
:amount="walletStore.memeToken?.unclaimedRewards"
:stake="stake"
v-if="stakeMenu"
>
<template v-slot:body>
<div class="btn btn-immortal stake-button" @click="stakeAndClaimAllRounds">
Stake & Claim Rest
</div>
<div
class="btn transparent small-text cancel-button text-center"
@click="stakeMenu = false"
>
Cancel
</div>
</template>
</stake-menu>
</Transition>
<div class="connected-stake-first-round small-text text-center">
You can claim, once the cycle is over.
</div>
</Transition>
<Transition name="smooth">
<stake-menu
v-model="tokenNumber"
@close="stakeMenu = false"
:amount="walletStore.memeToken?.unclaimedRewards"
:stake="stake"
v-if="stakeMenu"
>
<template v-slot:body>
<div class="btn btn-immortal stake-button" @click="stakeAndClaimAllRounds">
Stake & Claim Rest
</div>
<div class="btn transparent small-text cancel-button text-center" @click="stakeMenu = false">
Cancel
</div>
</template>
</stake-menu>
</Transition>
<div class="connected-stake-first-round small-text text-center">You can claim, once the cycle is over.</div>
</template>
<template v-else>
<div class="btn btn-immortal mid-mid-text text-center" @click="router.push({ name: 'home' })">
Go to Sacrifice
</div>
<div class="small-text text-center">Sacrifice to earn $BLOOD</div>
</template>
</template>
</stake-component>
<stake-component dense v-else>
<div class="text-center">All Claimed</div>
</stake-component>
</template>
<script setup>
@@ -51,10 +61,12 @@ import TokenLogo from "@/components/TokenLogo.vue";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { useTokenStore } from "@/stores/tokens";
import { useRewardLockerStore } from "@/stores/rewardlocker";
import { useRouter } from "vue-router";
const rewardLockerStore = useRewardLockerStore();
const walletStore = useWalletStoreV2();
const tokenStore = useTokenStore();
const router = useRouter();
const props = defineProps({
stakeonly: {
+104 -115
View File
@@ -1,75 +1,58 @@
<template>
<div class="connect-wallet-headline">Connect Wallet</div>
<div class="connectors-wrapper" v-if="!walletStore.connected">
<div
class="connectors-element"
v-for="connector in walletStore.config?.connectors"
@click="connectWallet(connector)"
>
<div class="connector-icon">
<img :src="`/assets/img/connectors/${connector.id}.svg`" :alt="`${connector.name} Logo`" />
<div class="connect-wallet-wrapper">
<template v-if="!walletStore.connected">
<div class="connect-wallet-headline low-mid-text">Connect your wallet</div>
<div class="connectors-wrapper">
<div
class="connectors-element card"
v-for="connector in walletStore.config?.connectors"
@click="connectWallet(connector)"
>
<div class="connector-icon">
<img :src="`/assets/img/connectors/${connector.id}.svg`" :alt="`${connector.name} Logo`" />
</div>
<div class="connector-name">{{ connector.name }}</div>
</div>
</div>
<div class="connector-name">{{ connector.name }}</div>
</div>
<div>
Are you coming from Binance, Poloniex, Kucoin or any other CEX?<br />
<br />
You don't have a wallet yet?<br /><br />
Follow these instructions first.
</div>
</div>
<div v-else>
<div class="connected-header">
<div class="connected-header-avatar">
<img :src="getblocky(walletStore.address)" alt="avatar" />
<div>Are you coming from Binance, Bybit, Kucoin or any other crypto exchange?</div>
<div>Follow these instructions first.</div>
</template>
<template v-else>
<div class="connected-header">
<div class="connected-header-avatar">
<img :src="getblocky(walletStore.address)" alt="avatar" />
</div>
<div class="connected-header-address">
{{ getAddressShortName(walletStore.address) }}
</div>
<div class="connected-header-logout" @click="disconnectWallet">
<font-awesome-icon :icon="['fas', 'fa-arrow-right-from-bracket']" />
</div>
</div>
<div class="connected-header-address">
{{ getAddressShortName(walletStore.address) }}
</div>
<div class="connected-header-logout" @click="disconnectWallet">
<font-awesome-icon :icon="['fas', 'fa-arrow-right-from-bracket']" />
</div>
</div>
<div class="connected-tokens-headline">Your Tokens</div>
<div class="connected-tokens">
<div class="connected-token" v-for="token in walletStore.token">
<token-name-price
:name="tokenStore.getToken(token.contractAddress).name"
:price="token.balanceOf"
></token-name-price>
<div class="connected-token-button">
<div class="bloodline-badge grey" @click="badgeClick(token)">
<div
class="bloodline-badge-text"
v-if="tokenStore.memeToken.contractAddress === token.contractAddress"
>
Buy
<div class="connected-tokens-headline">Your Tokens</div>
<div class="connected-tokens">
<div class="connected-token" v-for="token in walletStore.token">
<token-name-price
:name="tokenStore.getToken(token.contractAddress).name"
:price="token.balanceOf"
></token-name-price>
<div class="connected-token-button">
<div class="bloodline-badge grey" @click="badgeClick(token)">
<div
class="bloodline-badge-text"
v-if="tokenStore.memeToken.contractAddress === token.contractAddress"
>
Buy
</div>
<div v-else class="bloodline-badge-text">Sacrifice</div>
</div>
<div v-else class="bloodline-badge-text">Sacrifice</div>
</div>
<token-logo :img="tokenStore.getToken(token.contractAddress).logo" :alt="'test'"></token-logo>
</div>
<token-logo :img="tokenStore.getToken(token.contractAddress).logo" :alt="'test'"></token-logo>
</div>
</div>
<!-- <stake-component>
<template v-slot:headline> Staked </template>
<template v-slot:subheadline>
Stake for a 25% bonus on your sacrifice. Upper limit is your stake.
</template>
<template v-slot:actions>
<div class="connected-stake-buttons" v-if="!stakeMenu">
<div class="btn btn-immortal" @click="openStake">Stake</div>
<div
v-if="walletStore.memeToken?.staked === 0 && !stakeonly"
class="btn btn-immortal btn--disabled"
>
Unstake
</div>
<div v-else-if="!stakeonly" class="btn btn-immortal" @click="openUnstake">Unstake</div>
</div>
</template>
</stake-component> -->
<stake-component-v1></stake-component-v1>
<stake-component-v1 :variant="3"></stake-component-v1>
</template>
</div>
</template>
@@ -129,65 +112,71 @@ async function connectWallet(connector) {
</script>
<style lang="sass">
.connect-wallet-headline
font-family: Inter
font-size: 18px
font-style: normal
font-weight: 400
line-height: normal
.connectors-wrapper
.connect-wallet-wrapper
display: flex
flex-direction: column
gap: 8px
margin: 24px 0
.connectors-element
gap: 24px
.connectors-wrapper
display: flex
padding: 12px
border: 1px solid rgba(152, 161, 192, 0.24)
background-color: #202020
&:hover, &:active, &:focus
background-color: lighten(#202020, 20%)
cursor: pointer
.connector-icon
border-radius: 12px
width: 40px
overflow: hidden
height: 40px
.connector-name
padding: 0 8px
align-self: center
flex-direction: column
gap: 8px
.connectors-element
display: flex
padding: 12px
border: 1px solid rgba(152, 161, 192, 0.24)
background: var(--grey, #858585)
color: var(--midnight-black, #0F0F0F)
&:hover, &:active, &:focus
background-color: lighten(#858585, 20%)
cursor: pointer
.connector-icon
border-radius: 12px
width: 40px
overflow: hidden
height: 40px
.connector-name
padding: 0 8px
align-self: center
font-size: 16px
@media (min-width: 992px)
font-size: 18px
.connected-header
margin-bottom: 24px
display: flex
gap: 16px
align-items: center
.connected-header-avatar
img
border-radius: 8px
.connected-header-logout
margin-left: auto
svg
font-size: 25px
.connected-tokens-headline
font-size: 18px
margin-bottom: 16px
.connected-tokens
display: flex
flex-direction: column
gap: 16px
margin-bottom: 24px
.connected-token
.connected-header
margin-bottom: 24px
display: flex
gap: 16px
align-items: center
.connected-token-button
.connected-header-avatar
img
border-radius: 8px
.connected-header-logout
margin-left: auto
.bloodline-badge
padding: 4px 16px
color: black
font-size: 14px
svg
font-size: 25px
.connected-tokens-headline
font-size: 18px
margin-bottom: 16px
.connected-tokens
display: flex
flex-direction: column
gap: 16px
margin-bottom: 24px
.connected-token
display: flex
gap: 16px
align-items: center
.connected-token-button
margin-left: auto
.bloodline-badge
padding: 4px 16px
color: black
font-size: 14px
&:hover, &:active, &:focus
cursor: pointer
background-color: var(--grey-light)
</style>
+43
View File
@@ -0,0 +1,43 @@
<template>
<div class="loading-container">
<div class="blood"></div>
<div class="blood"></div>
<div class="blood"></div>
</div>
</template>
<style lang="sass">
.loading-container
display: flex
align-items: center
justify-content: center
gap: 10px
.blood
width: 15px
height: 15px
border: 1px solid black
border-radius: 0% 100% 100% 100%
transform: rotate(45deg)
animation: blink 1s infinite
@media (min-width: 992px)
width: 20px
height: 20px
.blood
&:nth-child(1)
animation-delay: -.2s
&:nth-child(2)
animation-delay: 0.2s
&:nth-child(3)
animation-delay: 0.5s
@keyframes blink
0%
background-color: transparent
50%
background-color: red
</style>
+141 -121
View File
@@ -1,17 +1,16 @@
<template>
<header>
<div class="navbar" :class="{ 'navbar--hidden': !showNavbar }">
<div class="navbar-inner">
<div class="navbar-icon">
<router-link to="/">
<img alt="logo" class="logo" src="/assets/img/vampir.png" />
</router-link>
</div>
<div class="navbar-text">
<router-link to="/">Bloodline</router-link>
</div>
<div class="navbar-center" v-if="!isMobile">
<!-- <div class="navbar-social-links">
<div class="navbar" :class="{ 'navbar--hidden': !showNavbar }">
<div class="navbar-inner">
<div class="navbar-icon">
<router-link to="/">
<img alt="logo" class="logo" src="/assets/img/vampir.png" />
</router-link>
</div>
<div class="navbar-text">
<router-link to="/">Bloodline</router-link>
</div>
<div class="navbar-center" v-if="!isMobile">
<!-- <div class="navbar-social-links">
<div class="social-bloodline-badge">
<div class="social-bloodline-badge-icon">
<font-awesome-icon icon="fa-brands fa-discord" />
@@ -31,45 +30,50 @@
<div class="social-bloodline-badge-text">Twitter</div>
</div>
</div> -->
</div>
<div class="navbar-end">
<div class="navbar-navigation mid-text" v-if="!isMobile">
<div
class="navbar-navigation-link"
v-for="link in links"
:key="link.name"
:class="{ active: link.name === route.name }"
@click="router.push(link.path)"
>
<div class="icon">
<img :src="link.icon" alt="" />
</div>
<div class="text">{{ link.title }}</div>
</div>
</div>
<div class="navbar-end">
<div class="navbar-navigation mid-text" v-if="!isMobile && connected">
<div
class="navbar-navigation-link"
v-for="link in links"
:key="link.name"
:class="{ active: link.name === route.name }"
@click="router.push(link.path)"
>
<div class="icon">
<img :src="link.icon" alt="" />
</div>
<div class="text">{{ link.title }}</div>
</div>
<div v-if="!isMobile">
<!-- <div v-if="!connected" class="btn btn-immortal" @click="walletStore.connectWallet">connect</div> -->
<div v-if="!address" class="btn btn-immortal mid-text" @click="showPanel = true">connect</div>
<!-- <span v-else @click="showPanel = true"> test</span> -->
<div class="login-icon-desktop mid-text" v-else @click="showPanel = true">
<img :src="getblocky(address)" alt="avatar" />
<div>{{ getAddressShortName(walletStore.address) }}</div>
</div>
<div v-if="!isMobile">
<!-- <div v-if="!connected" class="btn btn-immortal" @click="walletStore.connectWallet">connect</div> -->
<div v-if="!address" class="btn btn-immortal mid-text" @click="showPanel = true">connect</div>
<!-- <span v-else @click="showPanel = true"> test</span> -->
<div v-else @click="showPanel = true"><img :src="getblocky(address)" alt="avatar" /></div>
</div>
<div v-else @click="showPanel = true">
<div class="login-icon" v-if="!address">
<font-awesome-icon :icon="['fas', 'fa-arrow-right-to-bracket']" />
</div>
<div v-else @click="showPanel = true">
<div class="login-icon" v-if="!address">
<font-awesome-icon :icon="['fas', 'fa-arrow-right-to-bracket']" />
</div>
<div v-else><img :src="getblocky(address)" alt="avatar" /></div>
<div v-else>
<img :src="getblocky(address)" alt="avatar" />
</div>
</div>
</div>
</div>
</header>
</div>
</template>
<script setup>
import { storeToRefs } from "pinia";
import { ref, onMounted, onBeforeUnmount, inject } from "vue";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { getblocky } from "@/helper/helper.js";
import { getblocky, getAddressShortName } from "@/helper/helper.js";
import { useRoute, useRouter } from "vue-router";
const emit = defineEmits(["showPanel"]);
@@ -124,99 +128,115 @@ onBeforeUnmount(() => {
</script>
<style lang="sass" scoped>
header
// margin-bottom: 82px
// @media (min-width: 992px)
// margin-bottom: 128px
// margin-bottom: 82px
// @media (min-width: 992px)
// margin-bottom: 128px
.navbar
position: fixed
z-index: 3
.navbar
position: fixed
z-index: 3
box-sizing: border-box
background-color: #202020
width: 100%
transform: translate3d(0,0,0)
transition: transform .3s ease,visibility 0s .3s linear
height: 82px
@media (min-width: 992px)
height: 128px
// &.navbar--hidden
// transform: translate3d(0,-100%,0)
.navbar-inner
display: flex
padding: 16px 24px
box-sizing: border-box
background-color: #202020
width: 100%
transform: translate3d(0,0,0)
transition: transform .3s ease,visibility 0s .3s linear
height: 82px
height: 100%
align-items: center
@media (min-width: 992px)
height: 128px
// &.navbar--hidden
// transform: translate3d(0,-100%,0)
.navbar-inner
display: flex
padding: 16px 24px
box-sizing: border-box
height: 100%
align-items: center
@media (min-width: 992px)
padding: 16px 24px
.navbar-icon
img
height: 50px
width: 50px
.navbar-text
font-family: 'Vampire', sans-serif
font-size: 36px
margin-left: 16px
letter-spacing: 0.138em
line-height: 73.107px
.navbar-icon
img
height: 50px
width: 50px
@media (min-width: 992px)
font-size: 64px
a
text-decoration: none
color: white
.navbar-center
height: 75px
width: 75px
.navbar-text
font-family: 'Vampire', sans-serif
font-size: 36px
margin-left: 16px
letter-spacing: 0.138em
line-height: 73.107px
@media (min-width: 992px)
font-size: 64px
a
text-decoration: none
color: white
.navbar-center
display: flex
margin-left: auto
.navbar-social-links
display: flex
margin-left: auto
.navbar-social-links
gap: 18px
.social-bloodline-badge
font-size: 16px
padding: 8px 16px 8px 16px
border-radius: 14px
background-color: #0F0F0F
display: flex
gap: 18px
.social-bloodline-badge
font-size: 16px
padding: 8px 16px 8px 16px
border-radius: 14px
background-color: #0F0F0F
display: flex
&:hover,&:active,&:focus
background-color: lighten(#0F0F0F, 10%)
cursor: pointer
.social-bloodline-badge-icon
margin-right: 8px
.navbar-end
&:hover,&:active,&:focus
background-color: lighten(#0F0F0F, 10%)
cursor: pointer
.social-bloodline-badge-icon
margin-right: 8px
.navbar-end
display: flex
margin-left: auto
gap: 80px
.navbar-navigation
display: flex
margin-left: auto
gap: 80px
.navbar-navigation
align-items: center
gap: 48px
.navbar-navigation-link
display: flex
align-items: center
gap: 48px
.navbar-navigation-link
display: flex
gap: 8px
&.active
border-bottom: 2px solid white
&:active, &:hover, &:focus
cursor: pointer
.icon
img
width: 20px
height: 20px
gap: 8px
border-bottom: 2px solid transparent
&.active
border-bottom: 2px solid white
&:active, &:hover, &:focus
cursor: pointer
.icon
img
width: 20px
height: 20px
.login-icon
color: var(--white)
background-color: var(--purple)
padding: 8px
font-size: 25px
border-radius: 8px
width: 44px
height: 44px
display: flex
justify-content: center
align-items: center
.login-icon
color: var(--white)
background-color: var(--purple)
padding: 8px
font-size: 25px
border-radius: 8px
width: 44px
height: 44px
display: flex
justify-content: center
align-items: center
img
width: 32px
height: 32px
border-radius: 8px
.login-icon-desktop
display: flex
padding: 8px
align-items: center
gap: 16px
border-radius: 16px
background: var(--Background-grey, #2D2D2D)
&:hover,&:active,&:focus
cursor: pointer
img
width: 32px
height: 32px
border-radius: 8px
width: 45px
height: 45px
</style>
+244 -217
View File
@@ -1,161 +1,162 @@
<template>
<div class="sacrifice-wrapper card card--glow bloodline-wrapper">
<!-- {{ activeToken.allowance }} -->
<div class="sacrifice-inner">
<div class="sacrifice-headline">Select Sacrifice</div>
<div class="sacrifice-select-tokens">
<div class="sacrifice-tokens">
<div
class="sacrifice-token"
:class="[
{
'sacrifice-token--active': token.contractAddress === activeToken.contractAddress,
'bloodline-border': token.contractAddress === activeToken.contractAddress,
'bloodline-border--variant1': token.contractAddress === activeToken.contractAddress,
},
]"
v-for="token in props.data"
:key="token.contractAddress"
@click="tokenStore.changeActiveToken(token)"
>
<div class="sacrifice-token-logo">
<img v-if="isMobile" :src="token.logoMobile" alt="token logo" />
<img v-if="!isMobile" :src="token.logo" alt="token logo" />
</div>
<div class="sacrifice-token-name">{{ token.name }}</div>
<div class="sacrifice-headline">Select Sacrifice</div>
<div class="sacrifice-select-tokens">
<div class="sacrifice-tokens">
<div
class="sacrifice-token"
:class="[
{
'sacrifice-token--active': token.contractAddress === activeToken.contractAddress,
'bloodline-border': token.contractAddress === activeToken.contractAddress,
'bloodline-border--variant1': token.contractAddress === activeToken.contractAddress,
},
]"
v-for="token in props.data"
:key="token.contractAddress"
@click="tokenStore.changeActiveToken(token)"
>
<div class="sacrifice-token-logo">
<img v-if="isMobile" :src="token.logoMobile" alt="token logo" />
<img v-if="!isMobile" :src="token.logo" alt="token logo" />
</div>
<div class="sacrifice-token-name">{{ token.name }}</div>
</div>
</div>
<div class="sacrifice-from-to-wrapper" v-if="activeToken.contractAddress">
<div
:class="{
'sacrifice-from-wrapper': true,
'bloodline-border': true,
'bloodline-border--variant1': true,
purple: true,
}"
</div>
<div class="sacrifice-from-to-wrapper" v-if="activeToken.contractAddress">
<div
:class="{
'sacrifice-from-wrapper': true,
'bloodline-border': true,
'bloodline-border--variant1': true,
purple: true,
}"
>
<token-input
:modelValue="tokenNumber"
@input="
($event) => {
tokenNumber = $event.target.value;
return getRewardsFor($event.target.value);
}
"
:logo="activeToken.logo"
>
<div class="sarcrifice-from-input">
<input
@input="($event) => getRewardsFor($event.target.value)"
v-model="tokenNumber"
:placeholder="0"
/>
<div class="sacrifice-logo">
<img :src="activeToken.logo" alt="vampir" />
</div>
</div>
<div class="value-adder">
<template v-slot:message>
<div class="sacrifice-adder-step bloodline-badge" @click="addTokens(10000000)">+10m</div>
<div class="sacrifice-adder-step bloodline-badge" @click="addTokens(100000000)">+100m</div>
<div class="sacrifice-adder-step bloodline-badge" @click="addTokens(1000000000)">+1b</div>
<!-- <div class="sacrifice-adder-balance">Balance: {{ parseFloat(activeToken.balance) }}</div>
<div class="sacrifice-adder-max" @click="tokenNumber = parseFloat(activeToken.balance)">
Max
</div> -->
</div>
</div>
<div class="sacrifice-divider bloodline-devider">
<font-awesome-icon :icon="['fas', 'arrow-down']" />
</div>
<div
:class="{
'sacrifice-from-wrapper': true,
'bloodline-border': true,
'bloodline-border--variant1': true,
purple: output && output > 0,
}"
>
<div class="sarcrifice-from-input">
<div class="sacrifice-to-output">
<div class="sacrifice-to-output-coin">$BLOOD</div>
<div class="sacrifice-to-output-rewards">{{ output }}</div>
</div>
<div class="sacrifice-logo">
<img :src="activeToken.vamp?.logo" :alt="activeToken.vamp.name" />
</template>
</token-input>
</div>
<div class="sacrifice-divider bloodline-devider">
<font-awesome-icon :icon="['fas', 'arrow-down']" />
</div>
<div
:class="{
'sacrifice-to-wrapper': true,
'bloodline-border': true,
'bloodline-border--variant1': true,
purple: output && output > 0,
}"
>
<div class="sarcrifice-to-input">
<div class="sacrifice-to-output">
<div class="sacrifice-to-output-coin">$BLOOD</div>
<div class="sacrifice-to-output-rewards header">
{{ output }}
</div>
</div>
<div class="sacrifice-staking-bonus">
<div
class="sacrifice-staking-bonus-inner"
@click="
(e) => {
showStakingMenu = !showStakingMenu;
}
"
>
<div class="mid-mid-text">+ Staking Bonus</div>
<div class="icon">
<font-awesome-icon icon="chevron-down" />
</div>
<div class="sacrifice-logo">
<img :src="activeToken.vamp?.logo" :alt="activeToken.vamp.name" />
</div>
</div>
<div class="sacrifice-staking-bonus">
<div
class="sacrifice-staking-bonus-inner"
@click="
(e) => {
showStakingMenu = !showStakingMenu;
}
"
>
<div class="mid-mid-text">+ Staking Bonus</div>
<div class="icon">
<font-awesome-icon icon="chevron-down" />
</div>
<stake-component-v1 :variant="1" v-if="showStakingMenu">
<template v-slot:headline> {{ null }}</template>
</stake-component-v1>
</div>
<stake-component-v1 :variant="1" v-if="showStakingMenu">
<template v-slot:headline> {{ null }}</template>
</stake-component-v1>
<!-- <stake-component v-if="showStakingMenu" stakeonly class="variant1"></stake-component> -->
</div>
<!-- <stake-component v-if="showStakingMenu" stakeonly class="variant1"></stake-component> -->
</div>
<div class="sacrificed-info" v-if="state === 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" />
</div>
</div>
<div class="sacrificed-info" v-if="state === 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" />
</div>
<div class="sacrifice-fees-info-wrapper">
<div class="sacrifice-fees-img">
<img src="/assets/img/fuel-noozle.png" alt="fuel noozle" />
</div>
<div class="sacrifice-fees-body">
<div class="sacrifice-fees-body-header">
<div class="sacrifice-fees-body-header-title">Gas Subsidy</div>
<div class="sacrifice-fees-body-header-amount">≤30 Gwei</div>
</div>
<div class="sacrifice-fees-body-subheader">The clan pays your transaction.</div>
</div>
</div>
<div class="sacrifice-fees-info-wrapper">
<div class="sacrifice-fees-img">
<img src="/assets/img/fuel-noozle.png" alt="fuel noozle" />
</div>
<div class="sacrifice-buttons-function-wrapper">
<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"
v-if="
activeToken.allowance > 0 &&
activeToken.allowance >= tokenNumber &&
(state === 1 || state === 4)
"
@click="sacrificeToken(tokenNumber)"
>
Sacrifce
</div>
<div
class="btn btn-immortal sub-header"
v-if="
(!activeToken.allowance || activeToken.allowance < tokenNumber) &&
(state === 1 || state === 4)
"
@click="approveToken(tokenNumber)"
>
Approve Token
</div>
<div class="btn btn-immortal" disabled v-if="state === 2">Sign Transaction</div>
<div class="btn btn-immortal" disabled v-if="state === 3">Loading...</div>
</template>
<template v-else>
<div class="btn btn-immortal" @click="showPanel = true">Connect</div>
</template>
<div class="sacrifice-fees-body">
<div class="sacrifice-fees-body-header">
<div class="sacrifice-fees-body-header-title">Gas Subsidy</div>
<div class="sacrifice-fees-body-header-amount">≤30 Gwei</div>
</div>
<div class="sacrifice-fees-body-subheader">The clan pays your transaction.</div>
</div>
</div>
<div class="sacrifice-buttons-function-wrapper">
<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"
v-if="
activeToken.allowance > 0 &&
activeToken.allowance >= tokenNumber &&
(state === 1 || state === 4)
"
@click="sacrificeToken(tokenNumber)"
>
Sacrifice 🩸
</div>
<div
class="btn btn-immortal sub-header"
v-if="
(!activeToken.allowance || activeToken.allowance < tokenNumber) &&
(state === 1 || state === 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">
<loading-component></loading-component>
</div>
</template>
<template v-else>
<div class="btn btn-immortal sub-header" @click="showPanel = true">Connect</div>
</template>
</div>
</div>
</div>
</template>
<script setup>
import { ref, defineProps, watch, inject, computed } from "vue";
import { ref, defineProps, watch, inject, nextTick } from "vue";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { useTokenStore } from "@/stores/tokens";
import { useMemeburnerStore } from "@/stores/memeburner";
import StakeComponentV1 from "@/components/StakeComponentV1.vue";
import LoadingComponent from "@/components/LoadingComponent.vue";
import TokenInput from "@/components/TokenInput.vue";
import { storeToRefs } from "pinia";
import { waitForTransaction } from "@wagmi/core";
@@ -169,7 +170,7 @@ const walletStore = useWalletStoreV2();
// const { connected } = storeToRefs(walletStore);
const tokenStore = useTokenStore();
const { activeToken, loading } = storeToRefs(tokenStore);
const { activeToken } = storeToRefs(tokenStore);
const memeburnerStore = useMemeburnerStore();
@@ -187,6 +188,7 @@ const props = defineProps({
const tokenNumber = ref(null);
const output = ref(0);
const loading = ref(false);
/**
* state 0 enter amount
* state 1 rdy to go
@@ -227,8 +229,8 @@ async function approveToken(amount) {
const data = await waitForTransaction({
hash: hash,
});
activeToken.value.allowance = await tokenStore.allowance();
console.log("data", data);
activeToken.value.allowance = await tokenStore.allowance();
state.value = 1;
} catch (error) {
console.error(error);
@@ -239,21 +241,25 @@ async function approveToken(amount) {
}
async function getRewardsFor(value) {
if (!value || isNaN(value)) {
output.value = 0;
state.value = 0;
return;
loading.value = true;
try {
if (!value || isNaN(value)) {
output.value = 0;
state.value = 0;
return;
}
const rewardsForResult = await memeburnerStore.getRewardFor(
BigInt(value * Math.pow(10, activeToken.value.decimals))
);
state.value = 1;
output.value = rewardsForResult / BigInt(Math.pow(10, tokenStore.memeToken.decimals));
tokenStore.activeToken.rewards = output.value;
return output.value;
} catch (error) {
console.log("error", error);
} finally {
loading.value = false;
}
const rewardsForResult = await memeburnerStore.getRewardFor(
BigInt(value * Math.pow(10, activeToken.value.decimals))
);
// var test = await memeburnerStore.getRewardsFor(10000);
// console.log("test", test);
// const rewardsForResult = await tokenStore.getRewardsFor(10000);
state.value = 1;
output.value = rewardsForResult / BigInt(Math.pow(10, tokenStore.memeToken.decimals));
tokenStore.activeToken.rewards = output.value;
return output.value;
}
async function addTokens(value) {
@@ -271,88 +277,89 @@ async function addTokens(value) {
background-color: var(--primary)
padding: 24px
align-items: center
.sacrifice-inner
@media (min-width: 992px)
padding: 48px 64px
.sacrifice-headline
text-align: center
font-size: 24px
margin-bottom: 32px
@media (min-width: 992px)
padding: 48px 64px
.sacrifice-headline
text-align: center
font-size: 24px
margin-bottom: 32px
@media (min-width: 992px)
font-size: 36px
.sacrifice-select-tokens
display: flex
margin-bottom: 32px
.sacrifice-tokens
display: flex
width: 100%
justify-content: center
flex-wrap: wrap
gap: 12px
font-size: 36px
.sacrifice-select-tokens
display: flex
margin-bottom: 32px
.sacrifice-tokens
display: flex
width: 100%
justify-content: center
flex-wrap: wrap
gap: 12px
.sacrifice-token
border-radius: 16px
padding: 12px
cursor: pointer
background-color: #0F0F0F
text-align: center
user-select: none
border: 4px solid transparent
.sacrifice-token-logo
pointer-events: none
// @media (min-width: 992px)
// padding: 0
// background-color: unset
&.sacrifice-token--active
border-color: var(--purple)
.sacrifice-token-name
font-size: 16px
@media (min-width: 992px)
padding: 5px 26px
font-size: 24px
.sacrifice-buttons-function-wrapper
text-align: center
justify-content: center
display: block
@media (min-width: 992px)
display: flex
.btn
padding: 16px 64px
.sacrifice-fees-info-wrapper
display: flex
border: 2px dashed var(--grey)
color: var(--grey)
.sacrifice-token
border-radius: 16px
padding: 16px
font-size: 16px
gap: 16px
.sacrifice-fees-img
img
height: 46px
.sacrifice-fees-body
flex: 1 1 auto
.sacrifice-fees-body-header
display: flex
flex-direction: row
justify-content: space-between
margin-bottom: 8px
@media (min-width: 992px)
font-size: 24px
margin-bottom: 0
padding: 12px
cursor: pointer
background-color: #0F0F0F
text-align: center
user-select: none
border: 4px solid transparent
.sacrifice-token-logo
pointer-events: none
// @media (min-width: 992px)
// padding: 0
// background-color: unset
&.sacrifice-token--active
border-color: var(--purple)
.sacrifice-token-name
font-size: 16px
@media (min-width: 992px)
padding: 5px 26px
font-size: 24px
.sacrifice-buttons-function-wrapper
text-align: center
justify-content: center
display: block
@media (min-width: 992px)
display: flex
.btn
padding: 16px 64px
.sacrifice-fees-info-wrapper
display: flex
border: 2px dashed var(--grey)
color: var(--grey)
border-radius: 16px
padding: 16px
font-size: 16px
gap: 16px
.sacrifice-fees-img
img
height: 46px
.sacrifice-fees-body
flex: 1 1 auto
.sacrifice-fees-body-header
display: flex
flex-direction: row
justify-content: space-between
margin-bottom: 8px
@media (min-width: 992px)
font-size: 24px
margin-bottom: 0
.sacrifice-from-to-wrapper
display: flex
flex-direction: column
gap: 16px
width: 100%
@media (min-width: 992px)
gap: 32px
.sacrifice-from-wrapper,.sacrifice-to-wrapper
.sacrifice-from-wrapper
.sarcrifice-from-input
display: flex
margin-bottom: 8px
// height: 60px
@media (min-width: 992px)
height: 60px
input
width: 100%
height: 45px
@@ -370,7 +377,7 @@ async function addTokens(value) {
border-radius: 50%
pointer-events: none
@media (min-width: 992px)
height: 83px
height: 100%
width: auto
.sacrifice-to-output
flex: 1 1 auto
@@ -388,10 +395,14 @@ async function addTokens(value) {
gap: 6px
.sacrifice-adder-step
font-size: 14px
background: var(--grey, #858585)
color: var(--midnight-black, #0F0F0F)
@media (min-width: 992px)
font-size: 16px
&:hover,
&:active,
&:focus
background-color: var(--secondary)
background-color: var(--grey-light)
cursor: pointer
// .sacrifice-adder-balance
// margin-left: auto
@@ -404,6 +415,22 @@ async function addTokens(value) {
// color: darken(red, 10%)
// transform: scale(1.1)
// transition: transform 0s
.sacrifice-to-wrapper
display: flex
flex-direction: column
gap: 24px
.sarcrifice-to-input
display: flex
justify-content: space-between
.sacrifice-logo
img
width: 45px
height: 45px
border-radius: 50%
pointer-events: none
@media (min-width: 992px)
height: 82px
width: 82px
.sacrificed-info
display: flex
padding: 8px 24px
+4 -3
View File
@@ -32,6 +32,7 @@ function testClick(e) {
height: 100%
width: 100%
position: fixed
background-color: rgb(15, 15, 15, 0.7)
.slideout-wrapper
z-index: 100
height: 100svh
@@ -48,12 +49,12 @@ function testClick(e) {
margin-right: -400px
transition: margin-right 250ms ease 0s
width: auto
right: 0
bottom: unset
right: -30px
top: 0
&.open
margin-bottom: -82px
@media (min-width: 992px)
margin-right: 0
margin-right: 30px
.slideout-panel
width: 100%
height: 100%
+5 -2
View File
@@ -1,7 +1,7 @@
<!-- zukünftig card component -->
<template>
<div
class="connected-stake bloodline-border white card"
class="connected-stake bloodline-border card"
:class="{ 'card--dense': dense }"
@click="
(e) => {
@@ -77,6 +77,10 @@ function openUnstake() {
display: flex
flex-direction: column
gap: 16px
border: 2px solid var(--grey, #858585)
border-color: var(--grey, #858585)
@media (min-width: 992px)
padding: 8px 12px
&.connected-stake--variant1
background-color: transparent
border: none
@@ -97,5 +101,4 @@ function openUnstake() {
gap: 16px
div
flex: 1 1 50%
font-size: 18px
</style>
+132 -82
View File
@@ -1,94 +1,108 @@
<template>
<div
class="connected-stake bloodline-border white card"
:class="{ 'card--dense': dense, 'connected-stake--variant1': variant === 1 }"
@click="
(e) => {
e.preventDefault();
e.stopPropagation();
}
"
:class="{
'stake-component--variant1': props.variant === 1,
'stake-component--variant2': props.variant === 2,
'stake-component--variant3': props.variant === 3,
}"
>
<div class="connected-stake-headline mid-mid-text">
<div class="mid-text text-center" v-if="props.variant === 2">
<slot name="headline">Staked</slot>
</div>
<div class="low-mid-text text-center">
<slot name="subheadline">Stake for a 25% bonus on your sacrifice. Upper limit is your stake.</slot>
</div>
<div class="connected-stake-body">
<slot name="body">
<token-name-price
:name="tokenStore.getToken(walletStore.memeToken?.contractAddress)?.name"
: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>
</slot>
</div>
<slot name="actions">
<div class="connected-stake-buttons" v-if="!stakeMenu">
<div class="btn btn-immortal" disabled v-if="roundStore.currentRound === 1">Stake</div>
<div class="btn btn-immortal" v-else @click="openStake">Stake</div>
<div
class="connected-stake bloodline-border card"
:class="{ 'card--dense': dense, 'connected-stake--variant1': variant === 1 }"
@click="
(e) => {
e.preventDefault();
e.stopPropagation();
}
"
>
<div class="connected-stake-headline mid-mid-text">
<slot name="headline" v-if="variant !== 2">Staked</slot>
</div>
<div class="connected-stake-subheadline">
<slot name="subheadline"
>Stake for a 25% bonus on your sacrifice.<br />
Upper limit is your stake.</slot
>
</div>
<div class="connected-stake-body">
<slot name="body">
<token-name-price
:name="tokenStore.getToken(walletStore.memeToken?.contractAddress)?.name"
: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>
</slot>
</div>
<slot name="actions">
<div class="connected-stake-buttons" v-if="!stakeMenu">
<div class="btn btn-immortal mid-mid-text" disabled v-if="roundStore.currentRound === 1">Stake</div>
<div class="btn btn-immortal mid-mid-text" v-else @click="openStake">Stake</div>
<div
v-if="(walletStore.memeToken?.staked === 0 && !stakeonly) || roundStore.currentRound === 1"
class="btn btn-immortal btn--disabled mid-mid-text"
>
Unstake
</div>
<div v-else-if="!stakeonly" class="btn btn-immortal mid-mid-text" @click="openUnstake">Unstake</div>
</div>
<Transition name="smooth">
<stake-menu
v-model="tokenNumber"
@close="stakeMenu = false"
:stake="stake"
v-if="stakeMenu & !unstakeMenu"
>
<template v-slot:body>
<div
class="btn btn-immortal stake-button"
@click="rewardLockerStore.stakeBloodline(tokenNumber)"
>
Stake
</div>
<div
class="btn transparent small-text cancel-button text-center"
@click="stakeMenu = false"
>
Cancel
</div>
</template>
</stake-menu>
<div class="unstake-menu" v-else-if="stakeMenu & unstakeMenu">
<div class="low-mid-text text-center">
To prevent users from farming rewards you can claim your stake next cycle.
</div>
<div class="unstake-menu-actions">
<div class="btn btn-immortal stake-button" v-if="!loading" @click="orderUnstake">
Unstake Next Cycle
</div>
<div class="btn btn--disabled" v-else>Sign Transaction</div>
<div
class="btn transparent small-text cancel-button text-center"
@click="stakeMenu = false"
>
Cancel
</div>
</div>
</div>
</Transition>
<!-- todo v-if activeround -->
<div
v-if="(walletStore.memeToken?.staked === 0 && !stakeonly) || roundStore.currentRound === 1"
class="btn btn-immortal btn--disabled"
class="connected-stake-first-round small-text text-center"
v-if="roundStore.currentRound === roundStore.activeRound"
>
Unstake
No $BLOOD on the market. Staking is activated after the first cycle is finished.
</div>
<div v-else-if="!stakeonly" class="btn btn-immortal" @click="openUnstake">Unstake</div>
</div>
<Transition name="smooth">
<stake-menu
v-model="tokenNumber"
@close="stakeMenu = false"
:stake="stake"
v-if="stakeMenu & !unstakeMenu"
>
<template v-slot:body>
<div
class="btn btn-immortal stake-button"
@click="rewardLockerStore.stakeBloodline(tokenNumber)"
>
Stake
</div>
<div class="btn transparent small-text cancel-button text-center" @click="stakeMenu = false">
Cancel
</div>
</template>
</stake-menu>
<div class="unstake-menu" v-else-if="stakeMenu & unstakeMenu">
<div class="low-mid-text text-center">
To prevent users from farming rewards you can claim your stake next cycle.
</div>
<div class="unstake-menu-actions">
<div class="btn btn-immortal stake-button" v-if="!loading" @click="orderUnstake">
Unstake Next Cycle
</div>
<div class="btn btn--disabled" v-else>Sign Transaction</div>
<div class="btn transparent small-text cancel-button text-center" @click="stakeMenu = false">
Cancel
</div>
</div>
<div class="connected-stake-claim-info low-mid-text text-center">
You can claim your stake next cycle.
</div>
</Transition>
<!-- todo v-if activeround -->
<div
class="connected-stake-first-round small-text text-center"
v-if="roundStore.currentRound === roundStore.activeRound"
>
No $BLOOD on the market. Staking is activated after the first cycle is finished.
</div>
<div class="low-mid-text text-center">You can claim your stake next cycle.</div>
</slot>
<slot></slot>
<!-- <div class="connected-stake-buttons" v-if="!stakeMenu">
<div class="btn btn-immortal" @click="openStake">Stake</div>
<div v-if="walletStore.memeToken?.staked === 0 && !stakeonly" class="btn btn-immortal btn--disabled">
Unstake
</div>
<div v-else-if="!stakeonly" class="btn btn-immortal" @click="openUnstake">Unstake</div>
</div> -->
</slot>
<slot></slot>
</div>
</div>
</template>
@@ -149,6 +163,21 @@ async function orderUnstake() {
</script>
<style lang="sass">
.connected-stake-subheadline
font-size: 16px
@media (min-width: 992px)
font-size: 24px
.stake-component--variant2
border-radius: 16px
background: var(--darkgrey, #202020)
display: flex
flex-direction: column
gap: 24px
padding: 8px
@media (min-width: 992px)
padding: 32px 64px
.unstake-menu
display: flex
flex-direction: column
@@ -157,4 +186,25 @@ async function orderUnstake() {
display: flex
flex-direction: column
gap: 8px
.stake-component--variant3
.connected-stake
.connected-stake-headline
text-align: left
font-size: 18px
.connected-stake-subheadline
font-size: 16px
.connected-stake-body
.token-price-wrapper, .stake-reward
.token-name
font-size: 14px
.token-price
font-size: 24px
.connected-stake-buttons
.btn
font-size: 18px
.connected-stake-first-round
font-size: 14px
.connected-stake-claim-info
font-size: 14px
</style>
+3 -19
View File
@@ -1,35 +1,19 @@
<template>
<div class="stake-menu">
<div class="token-input">
<div class="sarcrifice-from-input">
<input
@input="emit('update:modelValue', Number($event.target.value))"
:value="props.modelValue"
:placeholder="0"
/>
</div>
<div class="value-adder">
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(25)">25%</div>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(50)">50%</div>
<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>
</div>
</div>
<!-- <token-input v-model="tokenNumber">
<token-input :modelValue="props.modelValue" @input="emit('update:modelValue', Number($event.target.value))">
<template v-slot:message>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(25)">25%</div>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(50)">50%</div>
<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>
</token-input> -->
</token-input>
<div class="stake-menu-actions">
<slot name="body">
<div class="input-balance">Balance: {{ walletStore.memeToken.balanceOf }}</div>
<div class="btn btn-immortal stake-button" @click="stakeBloodline" v-if="props.stake">Stake</div>
<div class="btn btn-immortal stake-button" @click="unstakeBloodline" v-else>Unstake for Next Cycle</div>
<div class="btn btn-immortal black cancel-button" @click="emit('close')">Cancel</div>
<div class="btn btn-immortal black" @click="emit('close')">Cancel</div>
</slot>
</div>
</div>
+5 -1
View File
@@ -62,7 +62,10 @@
<div v-else class="btn btn-immortal btn--disabled">Nothing to claim</div>
</div> -->
<div class="claim-button">
<template v-if="activeRound === currentRound">
<template v-if="!walletStore.connected">
<button class="btn btn-immortal sub-header" @click="showPanel = true">Connect</button>
</template>
<template v-else-if="activeRound === currentRound">
<button class="btn btn-immortal sub-header" @click="router.push({ name: 'home' })">Sacrifice</button>
</template>
<template v-else-if="getCurrentRoundData?.rewards_total > 0">
@@ -112,6 +115,7 @@ import StakeMenu from "@/components/StakeMenu.vue";
const clanRewards = ref(0);
const rewards = ref(0);
const isMobile = inject("isMobile");
const showPanel = inject("showPanel");
const rewardLockerStore = useRewardLockerStore();
const walletStore = useWalletStoreV2();
const roundStore = useRoundsStore();
+20 -5
View File
@@ -6,7 +6,11 @@
v-model="props.modelValue"
:placeholder="0"
/>
<div class="sacrifice-logo" v-if="props.logo">
<img :src="props.logo" alt="vampir" />
</div>
</div>
<div class="value-adder">
<slot class="value-adder" name="message"></slot>
</div>
@@ -16,6 +20,7 @@
<script setup>
const props = defineProps({
modelValue: Number,
logo: String,
});
const emit = defineEmits(["update:modelValue"]);
@@ -25,7 +30,8 @@ const emit = defineEmits(["update:modelValue"]);
.sarcrifice-from-input
display: flex
margin-bottom: 8px
// height: 60px
@media (min-width: 992px)
height: 60px
input
width: 100%
height: 45px
@@ -33,8 +39,18 @@ const emit = defineEmits(["update:modelValue"]);
border-radius: 16px
padding: 0 16px
@media (min-width: 992px)
font-size: 32px
font-size: 24px
height: auto
.sacrifice-logo
margin-left: 16px
img
width: 45px
height: 45px
border-radius: 50%
pointer-events: none
@media (min-width: 992px)
height: 100%
width: auto
.value-adder
display: flex
gap: 8px
@@ -46,7 +62,6 @@ const emit = defineEmits(["update:modelValue"]);
border-color: transparent
border-style: solid
&:hover,&:active, &:focus
color: var(--white)
border-color: var(--white)
background-color: var(--black)
background-color: var(--grey-light)
cursor: pointer
</style>
+3
View File
@@ -18,4 +18,7 @@ const props = defineProps({
height: 45px
border-radius: 50%
pointer-events: none
@media (min-width: 992px)
width: 65px
height: 65px
</style>
+4 -3
View File
@@ -1,7 +1,7 @@
<template>
<div class="token-price-wrapper">
<div class="token-name small-text">{{ props.name }}</div>
<div class="token-price number-mobile">{{ props.price }}</div>
<div class="token-price sub-header">{{ props.price }}</div>
</div>
</template>
@@ -14,6 +14,7 @@ const props = defineProps({
<style lang="sass">
.token-price-wrapper
.token-name
margin-bottom: 4px
display: flex
flex-direction: column
gap: 4px
</style>
+88
View File
@@ -0,0 +1,88 @@
<script>
export default {
name: `TransitionExpand`,
functional: true,
render(createElement, context) {
const data = {
props: {
name: `expand`,
},
on: {
afterEnter(element) {
// eslint-disable-next-line no-param-reassign
element.style.height = `auto`;
},
enter(element) {
const { width } = getComputedStyle(element);
/* eslint-disable no-param-reassign */
element.style.width = width;
element.style.position = `absolute`;
element.style.visibility = `hidden`;
element.style.height = `auto`;
/* eslint-enable */
const { height } = getComputedStyle(element);
/* eslint-disable no-param-reassign */
element.style.width = null;
element.style.position = null;
element.style.visibility = null;
element.style.height = 0;
/* eslint-enable */
// Force repaint to make sure the
// animation is triggered correctly.
// eslint-disable-next-line no-unused-expressions
getComputedStyle(element).height;
requestAnimationFrame(() => {
// eslint-disable-next-line no-param-reassign
element.style.height = height;
});
},
leave(element) {
const { height } = getComputedStyle(element);
// eslint-disable-next-line no-param-reassign
element.style.height = height;
// Force repaint to make sure the
// animation is triggered correctly.
// eslint-disable-next-line no-unused-expressions
getComputedStyle(element).height;
requestAnimationFrame(() => {
// eslint-disable-next-line no-param-reassign
element.style.height = 0;
});
},
},
};
return createElement(`transition`, data, context.children);
},
};
</script>
<style scoped>
* {
will-change: height;
transform: translateZ(0);
backface-visibility: hidden;
perspective: 1000px;
}
</style>
<style>
.expand-enter-active,
.expand-leave-active {
transition: height 1s ease-in-out;
overflow: hidden;
}
.expand-enter,
.expand-leave-to {
height: 0;
}
</style>