488 lines
11 KiB
Vue
488 lines
11 KiB
Vue
<template>
|
|
<div class="wallet-container">
|
|
<div class="header">
|
|
<div class="label">Wallet</div>
|
|
</div>
|
|
<div class="horizontal-bar"></div>
|
|
<div class="code" v-if="logined">
|
|
<span class="uuid">{{showAccount}}</span>
|
|
<div v-clipboard:copy="account"
|
|
v-clipboard:success="onCopy"
|
|
v-clipboard:error="onCopyError">
|
|
<svg-icon
|
|
name="copy" class="icCopy"></svg-icon>
|
|
</div>
|
|
</div>
|
|
<div class="tab-bar-net">
|
|
<div class="tab-item"
|
|
v-for="n in nets"
|
|
@click='changeNet(n.id)'
|
|
:key="n.id"
|
|
:class="{'active': currentNet===n.id}"
|
|
>
|
|
<span>{{n.name}}</span>
|
|
</div>
|
|
</div>
|
|
<div class="wallet">
|
|
<total-balance :currencies="currencies"></total-balance>
|
|
<coin-card
|
|
v-for="d in coinList"
|
|
:coin-data="d"
|
|
@coin-card-clicked = "onCardClicked"
|
|
:key="d.symbol"></coin-card>
|
|
</div>
|
|
<div class="header ingame"><span class="label">Ingame Currency</span>
|
|
</div>
|
|
<div class="horizontal-bar"></div>
|
|
<div class="wallet">
|
|
<placeholder-panel></placeholder-panel>
|
|
<coin-card
|
|
v-for="d in gameCoinList"
|
|
:coin-data="d"
|
|
@coin-card-clicked = "onGameCardClicked"
|
|
:key="d.symbol"></coin-card>
|
|
</div>
|
|
<price-picker-modal></price-picker-modal>
|
|
</div>
|
|
</template>
|
|
<script lang="ts">
|
|
import { Component, Vue, Watch } from 'vue-property-decorator'
|
|
import TotalBalance, { ICurrentData } from '@/components/market/wallet/TotalBalance.vue'
|
|
import CoinCard, { ICoinData } from '@/components/market/wallet/CoinCard.vue'
|
|
import GameCoinCard from '@/components/market/wallet/GameCoinCard.vue'
|
|
import { AppModule } from '@/store/modules/app'
|
|
import PlaceholderPanel from '@/components/market/wallet/PlaceholderPanel.vue'
|
|
import ChainManager from '@/chain/ChainManager'
|
|
import { CONTRACT_ADDRESS } from '@/configs/config_chain'
|
|
import { formatPrice } from '@/utils/chain.util'
|
|
import { getUserInfo } from '@/api/User'
|
|
import PricePickerModal, { SHOW_AMOUNT_MODAL } from '@/components/market/PricePickerModal.vue'
|
|
import { EventBus, SHOW_CHAIN_MODAL } from '@/utils/event-bus'
|
|
|
|
@Component({
|
|
name: 'WalletPanel',
|
|
components: {
|
|
PricePickerModal,
|
|
PlaceholderPanel,
|
|
GameCoinCard,
|
|
CoinCard,
|
|
TotalBalance
|
|
}
|
|
})
|
|
export default class WalletPanel extends Vue {
|
|
private currentNet: number = this.nets[0].id
|
|
chainManager = new ChainManager()
|
|
|
|
get nets() {
|
|
return [...new ChainManager().availableChains.values()]
|
|
}
|
|
|
|
get logined() {
|
|
return this.chainManager.isLogined
|
|
}
|
|
|
|
@Watch('logined')
|
|
private accountChange() {
|
|
this.changeNet(this.nets[0].id)
|
|
this.updateCurrencies()
|
|
this.updateGameCoins()
|
|
}
|
|
|
|
private currencies: ICurrentData[] = []
|
|
|
|
private coinList: ICoinData[] = [
|
|
{
|
|
name: 'CEBG Coin',
|
|
type: 0,
|
|
id: 'cec',
|
|
symbol: 'cec',
|
|
amount: '-',
|
|
icon: require('@/assets/market/cec.png'),
|
|
price: '-',
|
|
btnName: 'Deposit',
|
|
btnDisable: true
|
|
},
|
|
{
|
|
name: 'CEBG Gem',
|
|
type: 0,
|
|
id: 'ceg',
|
|
symbol: 'ceg',
|
|
amount: '-',
|
|
icon: require('@/assets/market/ceg.png'),
|
|
price: '-',
|
|
btnName: 'Deposit',
|
|
btnDisable: true
|
|
}
|
|
]
|
|
|
|
private gameCoinList: ICoinData[] = [
|
|
{
|
|
name: 'CEBG Coin',
|
|
type: 1,
|
|
id: 'diamond',
|
|
symbol: 'gCEC',
|
|
amount: '-',
|
|
icon: require('@/assets/market/cec.png'),
|
|
price: '-',
|
|
btnName: 'Claim',
|
|
btnDisable: true
|
|
},
|
|
{
|
|
name: 'CEBG Gem',
|
|
type: 1,
|
|
id: 'gold',
|
|
symbol: 'gCEG',
|
|
amount: '-',
|
|
icon: require('@/assets/market/ceg.png'),
|
|
price: '-',
|
|
btnName: 'Claim',
|
|
btnDisable: true
|
|
}
|
|
]
|
|
|
|
created() {
|
|
for (const net of this.nets) {
|
|
this.currencies.push({
|
|
name: `W${net.symbol.toUpperCase()}`,
|
|
amount: '-',
|
|
price: '-',
|
|
chain: net.id
|
|
})
|
|
}
|
|
}
|
|
|
|
updateDefaultData(data: ICoinData) {
|
|
data.amount = '-'
|
|
data.price = '-'
|
|
data.btnDisable = true
|
|
return data
|
|
}
|
|
|
|
get showAccount() {
|
|
return AppModule.accountShow
|
|
}
|
|
|
|
get account() {
|
|
return AppModule.accountId
|
|
}
|
|
|
|
onCopy(e: any) {
|
|
this.$message({
|
|
message: 'You just copied accountId',
|
|
type: 'success',
|
|
duration: 5 * 1000
|
|
})
|
|
}
|
|
|
|
onCopyError(e: any) {
|
|
this.$message({
|
|
message: 'Failed to copy texts',
|
|
type: 'error',
|
|
duration: 5 * 1000
|
|
})
|
|
}
|
|
|
|
changeNet(net: number) {
|
|
this.currentNet = net
|
|
const chainData = CONTRACT_ADDRESS[net]
|
|
for (let i = 0, l = this.coinList.length; i < l; i++) {
|
|
const data = this.updateDefaultData(this.coinList[i])
|
|
data.chain = net
|
|
data.address = chainData[data.symbol]
|
|
this.$set(this.coinList, i, data)
|
|
}
|
|
this.updateBalanceSet()
|
|
}
|
|
|
|
async updateCurrencies() {
|
|
for (let i = 0, l = this.currencies.length; i < l; i++) {
|
|
const data = this.currencies[i]
|
|
const currentData = CONTRACT_ADDRESS[data.chain]
|
|
const eth = await this.chainManager.getBalance(currentData.eth, data.chain)
|
|
data.amount = eth
|
|
this.$set(this.currencies, i, data)
|
|
}
|
|
}
|
|
|
|
async updateBalanceSet() {
|
|
const currentData = CONTRACT_ADDRESS[this.currentNet]
|
|
if (currentData) {
|
|
const cec = await this.chainManager.getBalance(currentData.cec, this.currentNet)
|
|
const ceg = await this.chainManager.getBalance(currentData.ceg, this.currentNet)
|
|
console.log(formatPrice(cec, 18), formatPrice(ceg, 18))
|
|
const updateCoinData = (i: number, amount: number) => {
|
|
const cecData = this.coinList[i]
|
|
cecData.amount = formatPrice(amount, 18)
|
|
cecData.btnDisable = amount === 0
|
|
this.$set(this.coinList, i, cecData)
|
|
}
|
|
updateCoinData(0, cec)
|
|
updateCoinData(1, ceg)
|
|
}
|
|
}
|
|
|
|
async onCardClicked(data: ICoinData) {
|
|
console.log('on coin card clicked: ', data)
|
|
let value = 0
|
|
try {
|
|
value = await this.pickAmount({
|
|
min: 1,
|
|
max: data.amount,
|
|
title: 'Please input amount to deposit'
|
|
})
|
|
} catch (err) {
|
|
this.$message({
|
|
type: 'info',
|
|
message: 'User cancel'
|
|
})
|
|
}
|
|
if (!value) {
|
|
return
|
|
}
|
|
|
|
try {
|
|
const res = await this.beginTransfer(data, value)
|
|
console.log(res)
|
|
const txHash = res.transactionHash
|
|
} catch (err) {
|
|
console.log(err)
|
|
this.$message({
|
|
type: 'info',
|
|
message: 'error transfer'
|
|
})
|
|
}
|
|
}
|
|
|
|
async beginTransfer(data: ICoinData, amount: number) {
|
|
return this.chainManager.transferToAccount({
|
|
to: '0x42448C6a38c08637218D8327b748F213fC2c0231',
|
|
amount: amount,
|
|
chainId: data.chain!,
|
|
address: data.address!
|
|
})
|
|
}
|
|
|
|
async onGameCardClicked(data: ICoinData) {
|
|
console.log('on game card clicked: ', data)
|
|
let value = 0
|
|
try {
|
|
value = await this.pickAmount({
|
|
min: 1,
|
|
max: data.amount,
|
|
title: 'Please input amount to claim'
|
|
})
|
|
} catch (err) {
|
|
this.$message({
|
|
type: 'info',
|
|
message: 'User cancel'
|
|
})
|
|
}
|
|
if (!value) {
|
|
return
|
|
}
|
|
console.log('begin claim')
|
|
}
|
|
|
|
async updateGameCoins() {
|
|
const data = { account: AppModule.accountId }
|
|
// const res: any = await getUserInfo(data)
|
|
const res: any = {
|
|
errcode: 0, // 错误码
|
|
errmsg: '', // 错误描述
|
|
info: { // struct BcUserInfo, 用户信息
|
|
account: '', // 账号
|
|
gold: 1000, // 金币
|
|
diamond: 2000 // 钻石
|
|
}
|
|
}
|
|
if (res.info) {
|
|
const info = res.info
|
|
for (let i = 0, l = this.gameCoinList.length; i < l; i++) {
|
|
const data = this.gameCoinList[i]
|
|
data.amount = info[data.id] || 0
|
|
data.btnDisable = data.amount === 0
|
|
this.$set(this.gameCoinList, i, data)
|
|
}
|
|
}
|
|
}
|
|
|
|
pickAmount(data: any) {
|
|
return new Promise<number>((resolve, reject) => {
|
|
data.current = data.current || data.min
|
|
data.confirmFun = (val: number) => {
|
|
resolve && resolve(val)
|
|
}
|
|
data.cancelFun = () => {
|
|
// eslint-disable-next-line prefer-promise-reject-errors
|
|
reject && reject('cancel select')
|
|
}
|
|
EventBus.$emit(SHOW_AMOUNT_MODAL, data)
|
|
})
|
|
}
|
|
}
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
@import '../../../scss/breakpoints.scss';
|
|
|
|
.wallet-container {
|
|
box-sizing: border-box;
|
|
color: white;
|
|
width: 1440px;
|
|
.tab-bar-net {
|
|
display: flex;
|
|
flex-direction: row;
|
|
margin-bottom: 5px;
|
|
.tab-item{
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
flex: none;
|
|
cursor: pointer;
|
|
font-weight: bold;
|
|
font-size: 1em;
|
|
line-height: 1.5em;
|
|
padding: 0.5em 2.125em;
|
|
text-transform: uppercase;
|
|
border: 1px solid #413482;
|
|
height: 2em;
|
|
border-radius: 0.2em;
|
|
color: #bcadf2;
|
|
background: transparent;
|
|
//clip-path: polygon(10% 0, 100% 0, 90% 100%, 0% 100%);
|
|
&:not(:first-child) {
|
|
margin-left: 0.5em;
|
|
}
|
|
&.active {
|
|
color: #ffffff;
|
|
background: #413482;
|
|
}
|
|
}
|
|
}
|
|
.code {
|
|
display: flex;
|
|
align-self: flex-start;
|
|
cursor: pointer;
|
|
margin-bottom: 1.25em;
|
|
.uuid {
|
|
font-size: 1em;
|
|
line-height: 1.5;
|
|
|
|
&:active {
|
|
opacity: 0.6;
|
|
}
|
|
}
|
|
|
|
.copy {
|
|
margin-left: 0.5em;
|
|
}
|
|
}
|
|
.ingame {
|
|
margin-top: 3.625em;
|
|
}
|
|
|
|
.icCopy {
|
|
margin-left: 3.625em;
|
|
align-self: center;
|
|
&:active {
|
|
opacity: 0.6;
|
|
}
|
|
}
|
|
|
|
.header {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
padding-bottom: 0.75em;
|
|
|
|
.label {
|
|
font-weight: bolder;
|
|
font-size: 1.375em;
|
|
line-height: 1.27;
|
|
color: #ffffff;
|
|
&.disable {
|
|
@include media('<tablet') {
|
|
color: #3c2885;
|
|
}
|
|
}
|
|
&.ingameCurrency {
|
|
margin-left: 2.1875em;
|
|
}
|
|
}
|
|
}
|
|
|
|
.horizontal-bar {
|
|
border: 0;
|
|
height: 1px;
|
|
background: #563cb8;
|
|
margin-bottom: 1.75em;
|
|
}
|
|
|
|
.wallet {
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: space-between;
|
|
}
|
|
}
|
|
@include media('<wide') {
|
|
.wallet-container{
|
|
width: 1024px;
|
|
font-size: 13px;
|
|
}
|
|
}
|
|
// Mobile
|
|
@include media('<tablet') {
|
|
.wallet-container {
|
|
width: 100%;
|
|
.show {
|
|
display: flex !important;
|
|
}
|
|
.hide {
|
|
display: none !important;
|
|
}
|
|
.headerCoin {
|
|
margin-top: 28px;
|
|
}
|
|
.ingame {
|
|
margin-top: 28px;
|
|
}
|
|
.wallet {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
.coinCard {
|
|
width: 100%;
|
|
margin-bottom: 20px;
|
|
}
|
|
}
|
|
.walletIngame {
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Tablet
|
|
@include media('>=tablet', '<desktop') {
|
|
.wallet-container {
|
|
width: 100%;
|
|
.ingame {
|
|
margin-top: 38px;
|
|
}
|
|
.headerCoin {
|
|
margin-top: 28px;
|
|
}
|
|
.wallet {
|
|
display: flex;
|
|
flex-direction: row;
|
|
flex-wrap: wrap;
|
|
justify-content: space-between;
|
|
|
|
.coinCard {
|
|
width: 293px;
|
|
margin-bottom: 20px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
</style>
|