OSDN Git Service

fix: no update for dom of 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             transactions: [],
211             maskShow: false,
212             start: 0,
213             limit: 10,
214             enterActive: EnterActive,
215             leaveActive: LeaveActive,
216         };
217     },
218     watch: {
219         '$route'(to, from) {
220             if (to.name.startsWith('menu')) {
221                 this.maskShow = true
222             } else if (from.name.startsWith('menu')) {
223                 this.maskShow = false
224             }
225
226             //account toggle by the list from menu
227             if (to.name == 'home' && to.params.selectedAccount != undefined && from.name == 'menu') {
228                 this.currentAccount = to.params.selectedAccount
229             }
230
231             // remove transition for some page
232             this.enterActive = EnterActive
233             this.leaveActive = LeaveActive
234             if (to.name == 'transfer-confirm' || from.name == 'transfer-confirm') {
235                 this.enterActive = ''
236                 this.leaveActive = ''
237             }
238         },
239         currentAccount(newVal, oldVal) {
240             if (newVal.guid == undefined) {
241                 return;
242             }
243
244             this.refreshTransactions(newVal.guid, newVal.address).then(transactions => {
245                 this.transactions = transactions
246             });
247         },
248     },
249     computed: {
250         shortAddress: function () {
251             return address.short(this.currentAccount.address)
252         },
253         accountBalance: function () {
254             return this.currentAccount.balance
255         }
256     },
257     methods: {
258         setupShortAddr(rawAddress) {
259             this.currentAccount.address_short = address.short(rawAddress);
260         },
261         setupClipboard() {
262             this.clipboard.on("success", e => {
263                 this.$dialog.show({
264                     header: this.$t("dialog.header"),
265                     body: this.$t("dialog.copy.success")
266                 });
267             });
268             this.clipboard.on("error", e => {
269                 this.$dialog.show({
270                     header: this.$t("dialog.header"),
271                     body: this.$t("dialog.copy.fail")
272                 });
273             });
274         },
275         setupRefreshTimer() {
276             // todo refresh all accounts
277
278             setInterval(() => {
279                 this.refreshBalance(this.currentAccount.guid)
280             }, 10000)
281         },
282         setupNetwork() {
283             this.network = localStorage.bytomNet;
284             account.setupNet(this.network);
285         },
286         networkToggle: function (val) {
287             localStorage.bytomNet = this.network;
288             account.setupNet(this.network);
289             this.refreshAccounts();
290         },
291         showQrcode: function () {
292             this.$refs.qrcode.open(this.currentAccount.address);
293         },
294         openMenu: function () {
295             this.$router.push({ name: 'menu', params: { accounts: this.accounts, selected: this.currentAccount } })
296         },
297         transferOpen: function () {
298             this.$router.push({ name: 'transfer', params: { account: this.currentAccount } })
299         },
300         handleScroll(vertical, horizontal, nativeEvent) {
301             if (vertical.process == 0) {
302                 this.start = 0;
303                 this.refreshTransactions(this.currentAccount.guid, this.currentAccount.address).then(transactions => {
304                     this.transactions = transactions
305                 });
306                 return;
307             }
308
309             if (vertical.process == 1) {
310                 this.start += this.limit;
311                 this.refreshTransactions(this.currentAccount.guid, this.currentAccount.address, this.start, this.limit).then(transactions => {
312                     transactions.forEach(transaction => {
313                         this.transactions.push(transaction);
314                     });
315                 });
316             }
317         },
318         refreshAccounts: function () {
319             account.list().then(accounts => {
320                 this.accounts = accounts;
321                 if (accounts.length == 0) {
322                     return;
323                 }
324
325                 if (localStorage.currentAccount != undefined) {
326                     this.currentAccount = JSON.parse(localStorage.currentAccount);
327                 } else {
328                     this.currentAccount = accounts[0];
329                 }
330             })
331         },
332         refreshBalance: function (guid) {
333             account.balance(guid).then(balance => {
334                 this.currentAccount.balance = balance;
335                 this.currentAccount = Object.assign({}, this.currentAccount);
336             }).catch(error => {
337                 console.log(error);
338             });
339         },
340         refreshTransactions: function (guid, address, start, limit) {
341             return new Promise((resolve, reject) => {
342                 transaction.list(guid, address, start, limit).then(ret => {
343                     let transactions = ret.result.data;
344                     if (transactions == null) {
345                         return;
346                     }
347
348                     this.transactionsFormat(transactions);
349                     console.log("formatTx", transactions);
350                     resolve(transactions)
351                 }).catch(error => {
352                     console.log(error);
353                     reject(error)
354                 });
355             })
356         },
357         transactionsFormat: function (transactions) {
358             transactions.forEach(transaction => {
359                 let inputSum = 0;
360                 let outputSum = 0;
361                 let selfInputSum = 0;
362                 let selfoutputSum = 0;
363                 let inputAddresses = [];
364                 let outputAddresses = [];
365                 transaction.inputs.forEach(input => {
366                     inputSum += input.amount;
367                     if (input.address == this.currentAccount.address) {
368                         selfInputSum += input.amount;
369                         return;
370                     }
371
372                     inputAddresses.push(input.address);
373                 });
374                 transaction.outputs.forEach(output => {
375                     outputSum += output.amount;
376                     if (output.address == this.currentAccount.address) {
377                         selfoutputSum += output.amount;
378                         return;
379                     }
380
381                     outputAddresses.push(output.address);
382                 });
383
384                 let val = selfoutputSum - selfInputSum;
385                 if (val > 0) {
386                     transaction.direct = "+";
387                     transaction.address = address.short(inputAddresses.pop());
388                 } else {
389                     val = selfInputSum - selfoutputSum;
390                     transaction.direct = "-";
391                     transaction.address = address.short(outputAddresses.pop());
392                 }
393                 transaction.val = Number(val / 100000000);
394                 transaction.fee = Number(inputSum - outputSum) / 100000000;
395             });
396         },
397     },
398     mounted() {
399         this.setupNetwork();
400         this.setupClipboard();
401         this.setupRefreshTimer();
402         this.refreshAccounts();
403     },
404     beforeDestroy() {
405         this.clipboard.destroy();
406     }
407 };
408 </script>