OSDN Git Service

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