OSDN Git Service

update assets fall back
[bytom/Byone.git] / src / views / home.vue
1 <style lang="" scoped>
2 .warp {
3     z-index: 1;
4 }
5
6 .topbar {
7     font-size: 19px;
8     display:flex;
9 }
10 .topbar .topbar-left {
11     width: 85px;
12     overflow: hidden;
13     text-overflow: ellipsis;
14     white-space: nowrap;
15     padding-top: 20px;
16     padding-left: 20px;
17 }
18 .topbar-left .btn-menu {
19     float: left;
20     margin-right: 8px;
21 }
22 .topbar-left .btn-menu i {
23     font-size: 100%;
24 }
25 .alias {
26     height: 25px;
27     font-size: 16px;
28     line-height: 28px;
29 }
30
31 .topbar .topbar-middle {
32     margin-top: 20px;
33     margin-right: 20px;
34     border: 2px solid #fff;
35     border-radius: 18px;
36     padding: 0 20px;
37     font: 12px system-ui;
38     text-align: center;
39     display: flex;
40     align-items: center;
41 }
42
43 .content {
44     margin-top: 25px;
45     text-align: center;
46     padding: 0 30px 10px;
47 }
48
49 .content .amount {
50     padding-bottom: 10px;
51 }
52 .content .token-amount {
53     font-size: 32px;
54     line-height: 45px;
55 }
56
57 .btn-send-transfer {
58   display: flex;
59   align-items: center;
60   justify-content: space-evenly;
61   text-align:center;
62   position: absolute;
63   width: 320px;
64   height: 102px;
65   left: 20px;
66   top: 165px;
67   background: #FFFFFF;
68   box-shadow: 0px 2px 16px rgba(0, 0, 0, 0.08);
69   border-radius: 4px;
70   color: black;
71   font-size: 12px;
72 }
73
74 .transaction-title{
75   margin-top: 55px;
76 }
77
78 .transaction-title h3 {
79     font-size: 14px;
80     font-weight: inherit;
81     padding: 10px 0 10px 20px;
82 }
83 .transactions {
84   font-size: 15px;
85   height: 283px;
86   overflow: auto;
87 }
88 .list-item {
89     position: relative;
90     display: block;
91     padding: 10px 20px;
92     height: 52px;
93      border-bottom: solid 1px rgba(0, 0, 0, 0.04)
94 }
95
96 .network-select{
97   text-transform: capitalize;
98 }
99
100 .btn-creation {
101     display: block;
102     width: 310px;
103     height: 48px;
104     margin: auto;
105     padding: 15px 0;
106     position: absolute;
107     bottom: 20px;
108     left: 20px;
109 }
110
111 .addr{
112   font-size: 12px;
113 }
114
115 .no-record{
116   display: block;
117 }
118
119   .bg-image{
120     height: 216px;
121   }
122
123 .icon{
124   width: 40px;
125   height: 40px;
126 }
127 .icon-crosschain-svg{
128   background-image: url('../assets/img/icon/crosschain.svg');
129 }
130 .icon-vote-svg{
131   background-image: url('../assets/img/icon/vote.svg');
132 }
133 .icon-receive-svg{
134   background-image: url('../assets/img/icon/receive.svg');
135 }
136 .icon-send-svg{
137   background-image: url('../assets/img/icon/send.svg');
138 }
139
140 </style>
141
142 <template>
143     <div class="warp">
144         <section class="bg-image">
145             <div class="topbar">
146                 <div class="topbar-left">
147                     <a class="btn-menu" @click="openMenu">
148                         <i class="iconfont icon-menu"></i>
149                     </a>
150                 </div>
151                 <div class="topbar-middle bg-secondary">
152                     <select class="network-select" :value="netType||'bytom'" @change="netTypeToggle">
153                         <option value="bytom">{{ $t('main.bytom') }} {{net}}</option>
154                         <option value="vapor">{{ $t('main.vapor') }} {{net}}</option>
155                     </select>
156                 </div>
157             </div>
158             <div class="content">
159                 <div v-if="address!=undefined" class="amount color-white">
160                     <span class="alias color-grey">{{currentAccount.alias}}</span>
161                     <div class="token-amount">
162                         {{accountBalance}}
163                     </div>
164                 </div>
165                 <div v-else>
166                   <p style="width: 250px; margin: 45px auto; text-align: center;">{{ $t('main.noAccount') }}</p>
167
168                 </div>
169             </div>
170             <div v-if="netType =='vapor' && address!=undefined" class="btn-send-transfer">
171
172                 <a @click="listVoteOpen">
173                   <div class="icon icon-vote-svg"></div>
174                   <div>{{ $t('main.vote') }}</div>
175                 </a>
176                 <a @click="crossChainOpen">
177                   <div class="icon icon-crosschain-svg"></div>
178                   <div>{{ $t('main.crossChain') }}</div>
179                 </a>
180                 <a  @click="showQrcode">
181                   <div class="icon icon-receive-svg"></div>
182                   <div>{{ $t('main.receive') }}</div>
183                 </a>
184                 <a  @click="transferOpen">
185                   <div class="icon icon-send-svg"></div>
186                   <div>{{ $t('main.send') }}</div>
187                 </a>
188             </div>
189             <div v-else-if="address!=undefined" class="btn-send-transfer">
190                 <a @click="showQrcode">
191                   <div class="icon icon-receive-svg"></div>
192                   <div>{{ $t('main.receive') }}</div>
193                 </a>
194                 <a @click="transferOpen">
195                   <div class="icon icon-send-svg"></div>
196                   <div>{{ $t('main.send') }}</div>
197                 </a>
198             </div>
199         </section>
200       <section v-if="address!=undefined" class="transaction-title">
201       <h3 class="color-black">{{ $t('main.asset') }}</h3>
202       </section>
203       <section class="transactions">
204         <div v-if="address!=undefined">
205         <div v-if="balances && balances.length > 0">
206           <ul class="list">
207             <li class="list-item" v-for="(balance, index) in balances" :key="index" @click="assetOpen(balance)">
208               <div class="float-right text-align-right">
209                 <div class="value">{{ itemBalance(balance) }}</div>
210                 <div class="addr color-grey">{{ formatCurrency(currentBalanceAmount(balance)) }}</div>
211               </div>
212               <div v-if="balance.asset.symbol!== 'Asset'">
213                 <div class="uppercase">
214                   {{balance.asset.symbol}}
215                 </div>
216
217                 <div class="addr color-grey">{{balance.asset.name}}</div>
218               </div>
219               <div v-else>
220                 <div>
221                   Asset
222                 </div>
223
224                 <div class="addr color-grey uppercase">{{ shortAddress(balance.asset.assetId) }}</div>
225               </div>
226
227             </li>
228           </ul>
229         </div>
230           <div v-else>
231             <ul class="list">
232               <li class="list-item" v-for="(asset, index) in defaultBalances" :key="index" @click="assetOpen(asset)">
233                 <div class="float-right text-align-right">
234                   <div class="value">{{ itemBalance(asset) }}</div>
235                   <div class="addr color-grey">{{ formatCurrency(asset[ currency ]) }}</div>
236                 </div>
237                 <div v-if="asset.asset.symbol!== 'Asset'">
238                   <div class="uppercase">
239                     {{asset.asset.symbol}}
240                   </div>
241
242                   <div class="addr color-grey">{{asset.asset.name}}</div>
243                 </div>
244                 <div v-else>
245                   <div>
246                     Asset
247                   </div>
248
249                   <div class="addr color-grey uppercase">{{shortAddress(asset.asset.assetId)}}</div>
250                 </div>
251
252               </li>
253             </ul>
254           </div>
255         </div>
256         <div v-else>
257           <router-link :to="{name: 'menu-account-creation'}">
258             <div class="bg-emptytx"></div>
259             <div>
260               <span class="color-lightgrey center-text no-record">{{$t('main.noAssetRecord')}}</span>
261             </div>
262             <a class="btn btn-primary btn-creation">{{ $t('main.create') }}</a>
263           </router-link>
264         </div>
265       </section>
266
267         <!-- child page -->
268         <div class="mask" v-show="maskShow"></div>
269         <transition :enter-active-class="enterActive" :leave-active-class="leaveActive">
270             <router-view></router-view>
271         </transition>
272
273     </div>
274 </template>
275
276 <script>
277 import address from "@/utils/address";
278 import account from "@/models/account";
279 import transaction from "@/models/transaction";
280 import { camelize } from "@/utils/utils";
281 import { BTM } from "@/utils/constants";
282 import { mapActions, mapGetters, mapState } from 'vuex'
283 import * as Actions from '@/store/constants';
284 import _ from 'lodash';
285 import { Number as Num } from "@/utils/Number"
286
287
288 const EnterActive = 'animated faster fadeInLeft';
289 const LeaveActive = 'animated faster fadeOutLeft';
290 export default {
291     name: "",
292     data() {
293         return {
294             transactions: [],
295             maskShow: false,
296             start: 0,
297             limit: 10,
298             enterActive: EnterActive,
299             leaveActive: LeaveActive,
300             defaultBalances: [
301               {
302                 asset:{
303                   assetId: BTM,
304                   name: "Bytom",
305                   symbol: "BTM",
306
307                 } ,
308                 availableBalance: 0,
309                 decimals: 8,
310                 inBtc: "0",
311                 inCny: "0",
312                 inUsd: "0"
313               }
314             ],
315         };
316     },
317     watch: {
318         '$route'(to, from) {
319             if (to.name.startsWith('menu')) {
320                 this.maskShow = true
321             } else if (from.name.startsWith('menu')) {
322                 this.maskShow = false
323             }
324
325             // remove transition for some page
326             this.enterActive = EnterActive
327             this.leaveActive = LeaveActive
328             if (to.name == 'transfer-confirm' || from.name == 'transfer-confirm') {
329                 this.enterActive = ''
330                 this.leaveActive = ''
331             }
332             if (from.name == 'transfer-confirm') {
333               this.setupNetwork()
334             }
335         },
336         currentAccount(newVal, oldVal) {
337             if (newVal.guid == undefined){
338               return;
339             }
340
341             let addr
342             if(this.netType === 'vapor'){
343               addr = newVal.vpAddress
344             }else{
345               addr = newVal.address
346             }
347         },
348     },
349     computed: {
350         accountBalance: function () {
351             let balance
352             const balances = this.balances
353
354             if(balances && balances.length >0 ){
355                 const currency = camelize(this.currency)
356                 balance = _.sumBy(balances, function(o) { return Number(o[currency]); })
357             }
358             return  Num.formatCurrency( (balance != null && balance != 0)? balance : '0.00', this.currency)
359         },
360         address: function(){
361           if(this.netType === 'vapor'){
362             return this.currentAccount.vpAddress
363           }else{
364             return this.currentAccount.address
365           }
366         },
367         balances: function(){
368           if(this.netType === 'vapor'){
369             return this.currentAccount.vpBalances
370           }else{
371             return this.currentAccount.balances
372           }
373         },
374         ...mapState([
375           'bytom'
376         ]),
377         ...mapGetters([
378           'currentAccount',
379           'accountList',
380           'net',
381           'netType',
382           'currency'
383         ])
384     },
385     methods: {
386       currentBalanceAmount: function (balance) {
387         return balance[ camelize(this.currency) ]
388       },
389       shortAddress: function (add) {
390         return address.short(add)
391       },
392       formatCurrency: function (num) {
393         return Num.formatCurrency(num, this.currency)
394       },
395       itemBalance: function(assetObj){
396         const asset = assetObj.asset
397         if(asset.assetId === BTM){
398           return Num.formatNue(assetObj.availableBalance,8)
399         }else{
400           return assetObj.availableBalance
401         }
402       },
403         setupRefreshTimer() {
404             setInterval(() => {
405                 this.refreshBalance(this.address)
406             }, 10000)
407         },
408         setupNetwork() {
409             account.setupNet(`${this.net}${this.netType}`);
410         },
411         netTypeToggle: function (event) {
412             const newNetType = event.target.value  ==='bytom'? '' :event.target.value;
413
414             if( newNetType !== this.netType){
415               const bytom = this.bytom.clone();
416
417               bytom.settings.netType = newNetType;
418
419               account.setupNet(`${this.net}${newNetType}`)
420               if(newNetType === 'vapor'&& !this.currentAccount.vpAddress){
421                 account.copy(this.currentAccount.guid).then(accounts => {
422                   //update currentAccount
423                   bytom.currentAccount = accounts
424
425                   //update AccountList
426                   const objectIndex = bytom.accountList.findIndex(a => a.guid == this.currentAccount.guid)
427                   bytom.accountList[objectIndex].vpAddress = accounts.vpAddress
428
429                   this[Actions.UPDATE_STORED_BYTOM](bytom).then(()=>{
430                     this.refreshBalance(this.currentAccount.vpAddress)
431                   })
432                 }).catch(e =>{
433                   if(e.message == 'Error: wallet has exist'){
434                     account.listVapor(this.currentAccount.guid).then(accounts => {
435                       //update currentAccount
436                       bytom.currentAccount = accounts
437
438                       const objectIndex = bytom.accountList.findIndex(a => a.guid == this.currentAccount.guid)
439                       bytom.accountList[objectIndex].vpAddress = accounts.vpAddress
440
441                       this[Actions.UPDATE_STORED_BYTOM](bytom).then(()=>{
442                         this.refreshBalance(this.currentAccount.vpAddress)
443                       })
444                     })
445
446                   }
447                 })
448               }else{
449                 this[Actions.UPDATE_STORED_BYTOM](bytom).then(()=>{
450                   this.refreshBalance(this.currentAccount.address)
451                 })
452               }
453             }
454         },
455         showQrcode: function () {
456           this.$router.push('received')
457         },
458         openMenu: function () {
459             this.$router.push('menu')
460         },
461         transferOpen: function () {
462             this.$router.push('transfer')
463         },
464         crossChainOpen: function () {
465             this.$router.push('crossChain')
466         },
467         listVoteOpen: function () {
468             this.$router.push('listVote')
469         },
470         assetOpen: function (asset) {
471             this[Actions.SET_CURRENT_ASSET](asset)
472             this.$router.push('asset')
473         },
474         refreshBalance: function (address) {
475           if(address){
476             account.balance(address)
477               .then((obj)=>{
478                 const balances = obj.balances
479                 const votes = obj.votes
480
481                 const balanceNotEqual = !_.isEqual(this.balances, balances)
482
483                 const voteNotEqual = (this.netType === 'vapor' && !_.isEqual(this.currentAccount.votes, votes))
484
485                 if(balanceNotEqual || voteNotEqual){
486                     //update AccountList
487
488                     const bytom = this.bytom.clone();
489                     const objectIndex = bytom.accountList.findIndex(a => a.guid == this.currentAccount.guid)
490
491                     if(balanceNotEqual){
492                       if(this.netType === 'vapor'){
493                         bytom.currentAccount.vpBalances = balances;
494                         bytom.accountList[objectIndex].vpBalances = balances
495                       }else{
496                         bytom.currentAccount.balances = balances;
497                         bytom.accountList[objectIndex].balances = balances
498                       }
499                     }
500
501                     if(voteNotEqual){
502                       bytom.currentAccount.votes = votes;
503                       bytom.accountList[objectIndex].votes = votes
504                     }
505
506                     this[Actions.UPDATE_STORED_BYTOM](bytom)
507                 }
508               })
509               .catch(error => {
510                 console.log(error);
511             });
512           }
513         },
514       ...mapActions([
515         Actions.UPDATE_STORED_BYTOM,
516         Actions.SET_CURRENT_ASSET,
517       ])
518     },
519     mounted() {
520         this.setupNetwork();
521         this.setupRefreshTimer();
522         this.refreshBalance(this.address)
523     },
524   };
525 </script>