OSDN Git Service

Fixed the record display issue for other asset.
[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 }
9 .topbar .topbar-left {
10     width: 120px;
11     overflow: hidden;
12     text-overflow: ellipsis;
13     white-space: nowrap;
14     padding-top: 20px;
15     padding-left: 20px;
16 }
17 .topbar-left .btn-menu {
18     float: left;
19     margin-right: 8px;
20 }
21 .topbar-left .btn-menu i {
22     font-size: 100%;
23 }
24 .topbar-left .alias {
25     height: 25px;
26     font-size: 19px;
27     line-height: 28px;
28 }
29
30 .topbar .topbar-right {
31     float: right;
32     margin-top: 20px;
33     margin-right: 20px;
34     border: 2px solid #fff;
35     border-radius: 18px;
36     padding: 0 10px;
37     font: 12px system-ui;
38     text-align: center;
39 }
40
41 .topbar-right .lamp {
42     display: inline-block;
43     width: 6px;
44     height: 6px;
45     border-radius: 50%;
46     background-color: #02f823;
47     margin-right: 2px;
48     position: relative;
49     top: -2px;
50 }
51
52 .content {
53     margin-top: 20px;
54     text-align: center;
55     padding: 0 30px 20px;
56 }
57 .content .token-icon {
58     display: inline-flex;
59     height: 40px;
60     width: 40px;
61     padding: 8px;
62     margin: 8px;
63 }
64 .content .amount {
65     padding-bottom: 10px;
66 }
67 .content .token-amount {
68     font-size: 45px;
69     line-height: 45px;
70 }
71 .token-amount .asset {
72     font-size: 18px;
73     margin-left: 2px;
74 }
75 .qrcode {
76     margin-left: 5px;
77     vertical-align: middle;
78     cursor: pointer;
79 }
80 .btn-transfer {
81     width: 200px;
82 }
83
84 .transaction-title h3 {
85     font-size: 18px;
86     font-weight: inherit;
87     color: #cacaca;
88     text-align: center;
89     padding: 5px 0;
90 }
91 .transactions {
92     font-size: 15px;
93     height: 273px;
94     overflow: hidden;
95 }
96 .transactions .list {
97     padding: 0 20px;
98 }
99 .list-item {
100     display: block;
101     padding: 5px 10px;
102     border-bottom: 1px solid #5e5e5e;
103 }
104
105 .list-item .value {
106     float: right;
107     margin-top: 13px;
108 }
109 .account-address {
110     cursor: pointer;
111 }
112 .btn-creation {
113     display: block;
114     width: 200px;
115     margin: 0 auto;
116 }
117 </style>
118
119 <template>
120     <div class="warp">
121         <section class="bg-green">
122             <div class="topbar">
123                 <div class="topbar-right">
124                     <i class="lamp"></i>
125                     <select v-model="network" @change="networkToggle">
126                         <option value="mainnet">{{ $t('main.mainNet') }}</option>
127                         <option value="testnet">{{ $t('main.testNet') }}</option>
128                     </select>
129                 </div>
130                 <div class="topbar-left">
131                     <a class="btn-menu" @click="openMenu">
132                         <i class="iconfont icon-menu"></i>
133                     </a>
134                     <span class="alias">{{currentAccount.alias}}</span>
135                 </div>
136             </div>
137             <div class="content">
138                 <img src="@/assets/logo.png" class="token-icon">
139                 <div v-if="currentAccount.address!=undefined" class="amount">
140                     <div class="token-amount">
141                         {{accountBalance}}
142                         <span class="asset">BTM</span>
143                     </div>
144                     <p class="account-address">
145                         <span class="address-text" :title="addressTitle" :data-clipboard-text="currentAccount.address">{{shortAddress}}</span>
146                         <i class="iconfont qrcode" @click="showQrcode">&#xe7dd;</i>
147                     </p>
148                 </div>
149                 <a v-if="currentAccount.address!=undefined" class="btn btn-primary btn-transfer" @click="transferOpen">{{ $t('main.transfer') }}</a>
150             </div>
151         </section>
152
153         <div v-if="currentAccount.address!=undefined">
154             <section class="transaction-title">
155                 <h3 class="bg-gray">{{ $t('main.record') }}</h3>
156             </section>
157             <section class="transactions">
158                 <vue-scroll @handle-scroll="handleScroll">
159                     <ul class="list">
160                         <li class="list-item" v-for="(transcation, index) in transactions" :key="index" @click="$router.push({name: 'transfer-info', params: {transcation: transcation, address: currentAccount.address}})">
161                             <div class="value">{{transcation.direct}} {{transcation.val.toFixed(2)}} BTM</div>
162                             <div>
163                                 <div v-if="transcation.is_confirmed" class="time">{{transcation.block_timestamp | moment}}</div>
164                                 <div v-else class="time">{{transcation.submission_timestamp | moment}}</div>
165                                 <div class="addr">{{transcation.address}}</div>
166                             </div>
167                         </li>
168                     </ul>
169                 </vue-scroll>
170             </section>
171         </div>
172         <div v-else>
173             <p style="width: 250px; margin: 30px auto; text-align: center;">{{ $t('main.noAccount') }}</p>
174             <router-link :to="{name: 'menu-account-creation'}">
175                 <a class="btn btn-primary btn-creation bg-green">{{ $t('main.create') }}</a>
176             </router-link>
177         </div>
178
179         <!-- child page -->
180         <div class="mask" v-show="maskShow"></div>
181         <transition :enter-active-class="enterActive" :leave-active-class="leaveActive">
182             <router-view></router-view>
183         </transition>
184
185         <!-- modal -->
186         <Qrcode ref="qrcode"></Qrcode>
187     </div>
188 </template>
189
190 <script>
191 import ClipboardJS from "clipboard";
192 import Menu from "@/views/homeMenu";
193 import Qrcode from "@/views/qrcode";
194 import Transfer from "@/views/transfer";
195 import TxInfo from "@/views/transferDetail";
196 import address from "@/utils/address";
197 import account from "@/models/account";
198 import transaction from "@/models/transaction";
199 import { BTM } from "@/utils/constants";
200
201 const EnterActive = 'animated faster fadeInLeft';
202 const LeaveActive = 'animated faster fadeOutLeft';
203 export default {
204     name: "",
205     components: {
206         Qrcode,
207     },
208     data() {
209         return {
210             network: "mainnet",
211             clipboard: new ClipboardJS(".address-text"),
212             addressTitle: this.$t("main.copy"),
213             accounts: [],
214             currentAccount: {},
215             transactions: [],
216             maskShow: false,
217             start: 0,
218             limit: 10,
219             enterActive: EnterActive,
220             leaveActive: LeaveActive,
221         };
222     },
223     watch: {
224         '$route'(to, from) {
225             if (to.name.startsWith('menu')) {
226                 this.maskShow = true
227             } else if (from.name.startsWith('menu')) {
228                 this.maskShow = false
229             }
230
231             //account toggle by the list from menu
232             if (to.name == 'home' && to.params.selectedAccount != undefined) {
233                 this.currentAccount = to.params.selectedAccount
234                 this.refreshAccounts();
235             }
236
237             // remove transition for some page
238             this.enterActive = EnterActive
239             this.leaveActive = LeaveActive
240             if (to.name == 'transfer-confirm' || from.name == 'transfer-confirm') {
241                 this.enterActive = ''
242                 this.leaveActive = ''
243             }
244         },
245         currentAccount(newVal, oldVal) {
246             if (newVal.guid == undefined) return;
247             localStorage.currentAccount = JSON.stringify(newVal);
248
249             this.refreshTransactions(newVal.guid, newVal.address).then(transactions => {
250                 this.transactions = transactions
251             });
252         },
253         'currentAccount.guid'(guid) {
254             if (guid == undefined) return;
255
256             this.refreshBalance(guid);
257         }
258     },
259     computed: {
260         shortAddress: function () {
261             return address.short(this.currentAccount.address)
262         },
263         accountBalance: function () {
264             return this.currentAccount.balance != 0 ? this.currentAccount.balance : '0.00'
265         }
266     },
267     methods: {
268         setupClipboard() {
269             this.clipboard.on("success", e => {
270                 this.$dialog.show({
271                     header: this.$t("dialog.header"),
272                     body: this.$t("dialog.copy.success")
273                 });
274             });
275             this.clipboard.on("error", e => {
276                 this.$dialog.show({
277                     header: this.$t("dialog.header"),
278                     body: this.$t("dialog.copy.fail")
279                 });
280             });
281         },
282         setupRefreshTimer() {
283             // todo refresh all accounts
284
285             setInterval(() => {
286                 this.refreshBalance(this.currentAccount.guid)
287             }, 10000)
288         },
289         setupNetwork() {
290             this.network = localStorage.bytomNet;
291             account.setupNet(this.network);
292         },
293         networkToggle: function (val) {
294             localStorage.bytomNet = this.network;
295             account.setupNet(this.network);
296             this.currentAccount = {}
297             this.refreshAccounts();
298         },
299         showQrcode: function () {
300             this.$refs.qrcode.open(this.currentAccount.address);
301         },
302         openMenu: function () {
303             this.$router.push({ name: 'menu', params: { accounts: this.accounts, selected: this.currentAccount } })
304         },
305         transferOpen: function () {
306             this.$router.push({ name: 'transfer', params: { account: this.currentAccount } })
307         },
308         handleScroll(vertical, horizontal, nativeEvent) {
309             if (vertical.process == 0) {
310                 this.start = 0;
311                 this.refreshTransactions(this.currentAccount.guid, this.currentAccount.address).then(transactions => {
312                     this.transactions = transactions
313                 });
314                 return;
315             }
316
317             if (vertical.process == 1) {
318                 this.start += this.limit;
319                 this.refreshTransactions(this.currentAccount.guid, this.currentAccount.address, this.start, this.limit).then(transactions => {
320                     transactions.forEach(transaction => {
321                         this.transactions.push(transaction);
322                     });
323                 });
324             }
325         },
326         refreshAccounts: function () {
327             account.list().then(accounts => {
328                 this.accounts = accounts;
329                 if (accounts.length == 0) {
330                     return;
331                 }
332
333                 if (this.currentAccount.guid == undefined) {
334                     this.currentAccount = accounts[0];
335                 }
336             })
337         },
338         refreshBalance: function (guid) {
339             account.balance(guid).then(balance => {
340                 this.currentAccount.balance = balance;
341                 this.currentAccount = Object.assign({}, this.currentAccount);
342             }).catch(error => {
343                 console.log(error);
344             });
345         },
346         refreshTransactions: function (guid, address, start, limit) {
347             return new Promise((resolve, reject) => {
348                 transaction.list(guid, address, start, limit).then(ret => {
349                     let transactions = ret.result.data;
350                     if (transactions == null) {
351                         return;
352                     }
353
354                     const formattedTx = this.transactionsFormat(transactions);
355                     console.log("formatTx", formattedTx);
356                     resolve(formattedTx)
357                 }).catch(error => {
358                     console.log(error);
359                     reject(error)
360                 });
361             })
362         },
363         transactionsFormat: function (transactions) {
364           const formattedTransactions = []
365           const assetID = BTM
366
367           transactions.forEach(transaction => {
368             const balanceObject = transaction.balances
369               .filter(b => b.asset === assetID);
370
371             if(balanceObject.length ===1 ){
372
373                 const inputAddresses = transaction.inputs
374                   .filter(input => input.asset === assetID && input.address !== this.currentAccount.address)
375                   .map(input => input.address)
376
377                 const outputAddresses = transaction.outputs
378                   .filter(output => output.asset === assetID && output.address !== this.currentAccount.address)
379                   .map(output => output.address)
380
381
382                 const val  = assetID===BTM ? Number(balanceObject[0].amount)/ 100000000 : Number(balanceObject[0].amount);
383
384                 if (val > 0) {
385                     transaction.direct = "+";
386                     transaction.address = address.short(inputAddresses.pop());
387                 } else {
388                     transaction.direct = "-";
389                     transaction.address = address.short(outputAddresses.pop());
390                 }
391
392                 transaction.val = Math.abs(val);
393                 transaction.fee = transaction.fee / 100000000;
394
395                 formattedTransactions.push(transaction);
396               }
397             });
398           return formattedTransactions;
399         },
400     },
401     mounted() {
402         this.currentAccount = JSON.parse(localStorage.currentAccount);
403         this.setupNetwork();
404         this.setupClipboard();
405         this.setupRefreshTimer();
406         this.refreshAccounts();
407     },
408     beforeDestroy() {
409         this.clipboard.destroy();
410     }
411 };
412 </script>