OSDN Git Service

0bf5d64691b85aa5e0640ee9162966f612a2e23c
[bytom/Byone.git] / src / views / assetList.vue
1 <style lang="" scoped>
2   .topbar {
3     font-size: 19px;
4     display:flex;
5   }
6   .topbar .topbar-left {
7     overflow:hidden;
8     white-space:nowrap;
9   }
10
11   .topbar .topbar-middle {
12     margin-top: 10px;
13     padding: 0 20px;
14     text-align: center;
15     width: 245px;
16   }
17
18 .topbar-left .btn-menu i {
19     font-size: 100%;
20 }
21 .alias {
22     font-size: 13px;
23 }
24
25 .content {
26     text-align: center;
27     padding: 20px 30px;
28 }
29
30 .content .amount {
31     padding-bottom: 10px;
32 }
33 .content .token-amount {
34     font-size: 32px;
35     line-height: 45px;
36 }
37
38 .transaction-title h3 {
39     font-size: 16px;
40     font-weight: inherit;
41     padding: 10px 0 10px 20px;
42 }
43 .transactions {
44   font-size: 15px;
45   height: 340px;
46 }
47 .list-item {
48     padding: 10px 20px;
49     display: flex;
50     justify-content: space-between;
51     position: relative;
52 }
53
54 .list-item:after {
55     content:"";
56     background: #e0e0e0;
57     position: absolute;
58     bottom: 0;
59     left: 20px;
60     height: 1px;
61     width: 90%;
62 }
63 .addr{
64   font-size: 12px;
65 }
66
67
68 .no-record{
69   display: block;
70 }
71
72   .symbol{
73     margin-bottom: -8px;
74     font-size:15px;
75   }
76
77 </style>
78
79 <template>
80     <div class="warp-chlid bg-white">
81         <section class="bg-image">
82           <div class="topbar">
83             <div class="topbar-left">
84               <i class="iconfont icon-back" @click="close"></i>
85             </div>
86             <div class="topbar-middle">
87               <div v-if="currentAsset!=undefined" class="amount color-white">
88                 <div v-if="currentAsset.asset.symbol!=='Asset'">
89                   <div class="symbol">
90                     {{currentAsset.asset.symbol}}
91                   </div>
92
93                   <div class="alias color-grey">{{currentAsset.asset.name}}</div>
94                 </div>
95                 <div v-else>
96                   <div class="symbol">
97                     Asset
98                   </div>
99
100                   <div class="alias color-grey">{{shortAddress(currentAsset.asset.asset)}}</div>
101                 </div>
102               </div>
103             </div>
104           </div>
105             <div class="content">
106                 <div v-if="currentAsset!=undefined" class="amount color-white">
107                     <div class="token-amount">
108                         {{itemBalance(currentAsset)}}
109                     </div>
110                     <div>{{formatCurrency(currentAsset[ camelize(currency) ])}}</div>
111                 </div>
112             </div>
113         </section>
114             <section class="transaction-title">
115                 <h3 class="bg-gray color-grey">{{ $t('main.record') }}</h3>
116             </section>
117             <section class="transactions">
118                   <div class="transactions" v-if="transactions.length != 0">
119                       <vue-scroll ref="vs" @handle-scroll="handleScroll">
120                       <ul class="list">
121                           <li class="list-item" v-for="(transaction, index) in transactions" :key="index" @click="$router.push({name: 'transfer-info', params: {transaction: transaction, address: currentAccount.address}})">
122                               <div>
123                                   <div>{{transaction.address}}</div>
124                                   <div class="addr color-grey" v-if="transaction.hasOwnProperty('blockTimestamp')">
125                                     {{transaction.submissionTimestamp | moment}}
126                                   </div>
127                                   <div class="addr color-grey" v-else>
128                                     {{ $t('main.unconfirmed') }}
129                                   </div>
130                               </div>
131                               <div class="text-align-right">
132                                 <div class="value">{{transaction.direct}} {{transaction.val}}</div>
133                                 <div v-if="transaction.type == 'vote'" class="addr color-grey">{{ $t('listVote.vote')}} {{transaction.vAmount}}</div>
134                                 <div v-else-if="transaction.type == 'veto'" class="addr color-grey">{{ $t('listVote.cancelVote')}}  {{transaction.vAmount}}</div>
135                                 <div v-else-if="transaction.type == 'crossChain'" class="addr color-grey">{{ $t('crossChain.title')}}</div>
136                               </div>
137                           </li>
138                       </ul>
139                   </vue-scroll>
140                   </div>
141                   <div v-else>
142                       <div class="bg-emptytx"></div>
143                       <div>
144                           <span class="color-lightgrey center-text no-record">{{$t('main.noRecord')}}</span>
145                       </div>
146                   </div>
147             </section>
148
149     </div>
150 </template>
151
152 <script>
153 import address from "@/utils/address";
154 import query from "@/models/query";
155 import transaction from "@/models/transaction";
156 import { camelize } from "@/utils/utils";
157 import { BTM } from "@/utils/constants";
158 import { mapActions, mapGetters, mapState } from 'vuex'
159 import * as Actions from '@/store/constants';
160 import _ from 'lodash';
161 import { Number as Num } from "@/utils/Number"
162
163
164 const EnterActive = 'animated faster fadeInLeft';
165 const LeaveActive = 'animated faster fadeOutLeft';
166 export default {
167     name: "",
168     data() {
169         return {
170             asset:null,
171             transactions: [],
172             maskShow: false,
173             start: 0,
174             limit: 10,
175             enterActive: EnterActive,
176             leaveActive: LeaveActive,
177         };
178     },
179     watch: {
180         '$route'(to, from) {
181             if (to.name.startsWith('menu')) {
182                 this.maskShow = true
183             } else if (from.name.startsWith('menu')) {
184                 this.maskShow = false
185             }
186
187             // remove transition for some page
188             this.enterActive = EnterActive
189             this.leaveActive = LeaveActive
190         },
191       'currentAccount.balances'() {
192         this.$refs['vs'].scrollTo(
193           {
194             y: 0
195           },
196           500,
197           'easeInQuad'
198         );
199           this.start = 0
200           this.refreshTransactions( this.start, this.limit).then(transactions => {
201             this.transactions = transactions
202           });
203       },
204     },
205     computed: {
206       address: function(){
207         if(this.netType === 'vapor'){
208           return this.currentAccount.vpAddress
209         }else{
210           return this.currentAccount.address
211         }
212       },
213         ...mapState([
214           'bytom',
215           'currentAsset',
216           'listVote'
217         ]),
218         ...mapGetters([
219           'currentAccount',
220           'currency',
221           'netType'
222         ])
223     },
224     methods: {
225       camelize: function (object) {
226         return camelize(object)
227       },
228       close: function () {
229         this.$router.go(-1)
230       },
231       shortAddress: function (add) {
232         return address.short(add)
233       },
234       formatCurrency: function (num) {
235         return Num.formatCurrency(num, this.currency)
236       },
237       itemBalance: function(asset){
238         if(asset.asset === BTM){
239           return Num.formatNue(asset.availableBalance,8)
240         }else{
241           return Num.formatNue(asset.availableBalance,asset.decimals)
242         }
243
244       },
245         handleScroll(vertical, horizontal, nativeEvent) {
246             if (vertical.process == 0) {
247                 this.start = 0;
248                 this.refreshTransactions( this.start, this.limit).then(transactions => {
249                     this.transactions = transactions
250                 });
251                 return;
252             }
253
254             if ( (vertical.process == 1) && (this.transactions.length == (this.start+1)*this.limit) ) {
255                 this.start += this.limit;
256                 this.refreshTransactions( this.start, this.limit).then(transactions => {
257                     transactions.forEach(transaction => {
258                         this.transactions.push(transaction);
259                     });
260                 });
261             }
262         },
263         refreshTransactions: function (start, limit) {
264             return new Promise((resolve, reject) => {
265                 transaction.list(this.address, this.currentAsset.asset.assetId, start, limit).then(transactions => {
266                   if (transactions == null) {
267                         return;
268                     }
269
270                     const formattedTx = this.transactionsFormat(transactions);
271                     resolve(formattedTx)
272                 }).catch(error => {
273                     console.log(error);
274                     reject(error)
275                 });
276             })
277         },
278         transactionsFormat: function (transactions) {
279           const formattedTransactions = []
280           const assetID = this.currentAsset.asset.assetId
281
282           transactions.forEach(transaction => {
283             const balanceObject = transaction.balances
284               .filter(b => b.asset.assetId === assetID);
285
286             const filterInput = transaction.types.includes('veto')
287             const filterOutput = transaction.types.includes('vote')
288
289             if(filterInput){
290               transaction.type = 'veto'
291               const inAmount = _.sumBy((transaction.inputs.filter(i => i.type ==='veto')), 'amount')
292               const outAmount = _.sumBy((transaction.outputs.filter(i => i.type ==='vote')), 'amount')
293               transaction.pubkey = filterInput.vote
294               transaction.vAmount =  Num.formatNue(inAmount-outAmount,8)
295             }else if(filterOutput){
296               const outAmount = _.sumBy((transaction.outputs.filter(i => i.type ==='vote')), 'amount')
297               transaction.pubkey = filterOutput.vote
298               transaction.vAmount =  Num.formatNue(outAmount,8)
299               transaction.type = 'vote'
300             }else if(transaction.types.includes('out_crosschain')){
301               transaction.type = 'crossChain'
302               if(this.netType === 'vapor'){
303                 transaction.cDirection ='Vapor -> Bytom'
304               }else{
305                 transaction.cDirection ='Bytom -> Vapor'
306               }
307             }else if(transaction.types.includes('in_crosschain')){
308               transaction.type = 'crossChain'
309               if(this.netType === 'vapor'){
310                 transaction.cDirection ='Bytom -> Vapor'
311               }else{
312                 transaction.cDirection ='Vapor -> Bytom'
313               }
314             }
315
316             const inputAddresses = transaction.inputs
317               .filter(input => input.asset.assetId === assetID && input.address !== this.currentAccount.address)
318               .map(input => input.address)
319
320             const outputAddresses = transaction.outputs
321               .filter(output => output.asset.assetId === assetID && output.address !== this.currentAccount.address)
322               .map(output => output.address)
323
324             if(balanceObject.length ===1 ){
325                 let val = Math.abs(balanceObject[0].amount)
326
327                 if (Number(balanceObject[0].amount) > 0) {
328                     transaction.direct = "+";
329                     const resultAddr = inputAddresses.pop()
330                     transaction.address = (resultAddr && resultAddr.includes(' '))?resultAddr:address.short(resultAddr);
331                 } else {
332                     transaction.direct = "-";
333                     const resultAddr = outputAddresses.pop()
334                     transaction.address = (resultAddr && resultAddr.includes(' '))?resultAddr:address.short(resultAddr);
335                 }
336
337                 transaction.val =  val ;
338
339                 formattedTransactions.push(transaction);
340               }else{
341                 transaction.val =  0
342                 transaction.address = address.short(this.currentAccount.address)
343
344                 formattedTransactions.push(transaction);
345               }
346             });
347           return formattedTransactions;
348         },
349       ...mapActions([
350         Actions.UPDATE_STORED_BYTOM,
351         Actions.SET_LIST_VOTE
352       ])
353     },
354     mounted() {
355         this.refreshTransactions( this.start, this.limit).then(transactions => {
356           this.transactions = transactions
357         });
358         if(this.listVote.length == 0 && this.netType === 'vapor'){
359           query.chainStatus().then(resp => {
360             if(resp){
361               const votes =  resp.consensusNodes.map( (item, index) => {
362                 item.rank = index+1;
363                 return item
364               });
365               this[Actions.SET_LIST_VOTE](votes)
366             }
367           })
368         }
369     },
370   };
371 </script>