OSDN Git Service

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