OSDN Git Service

updtate the sideBar style.
[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: 85px;
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 10px;
37     font: 12px system-ui;
38     text-align: center;
39 }
40
41 .topbar-middle .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: 25px;
54     text-align: center;
55     padding: 0 30px 10px;
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: 32px;
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
81 .btn-send-transfer {
82     display: flex;
83     align-items: center;
84     justify-content: center;
85 }
86 .btn-send-transfer .btn {
87     width: 160px;
88     height: 48px;
89     line-height: 27px;
90     font-size: 16px;
91 }
92
93 .btn-received {
94     background: #0DBF37;
95     border-radius:4px 0px 0px 0px;
96 }
97 .btn-received:active,
98 .btn-received:hover,.btn-received:focus {
99     background: #05A02A;
100 }
101
102 .btn-transfer {
103     background: #035BD4;
104     border-radius:0px 4px 0px 0px;
105 }
106 .btn-transfer:active,
107 .btn-transfer:hover,.btn-transfer:focus {
108   background: #044BAF;
109 }
110
111 .transaction-title h3 {
112     font-size: 16px;
113     font-weight: inherit;
114     padding: 10px 0 10px 20px;
115 }
116 .transactions {
117     font-size: 15px;
118     height: 273px;
119     overflow: hidden;
120 }
121 .list-item {
122     position: relative;
123     display: block;
124     padding: 10px 20px;
125 }
126
127 .list-item:after {
128     content:"";
129     background: #e0e0e0;
130     position: absolute;
131     bottom: 0;
132     left: 20px;
133     height: 1px;
134     width: 90%;
135 }
136
137 .list-item .value {
138     float: right;
139     margin-top: 13px;
140 }
141 .account-address {
142     cursor: pointer;
143 }
144 .btn-creation {
145     display: block;
146     width: 310px;
147     height: 48px;
148     margin: auto;
149     padding: 15px 0;
150     position: absolute;
151     bottom: 20px;
152     left: 20px;
153 }
154
155 .time, .value{
156   font-weight: 500;
157   font-size: 16px;
158 }
159 .addr{
160   font-size: 12px;
161 }
162 .no-tx-img{
163   width: 100px;
164   height: 100px;
165 }
166 .no-record{
167   display: block;
168 }
169
170 </style>
171
172 <template>
173     <div class="warp">
174         <section class="bg-image">
175             <div class="topbar">
176                 <div class="topbar-left">
177                     <a class="btn-menu" @click="openMenu">
178                         <i class="iconfont icon-menu"></i>
179                     </a>
180                 </div>
181                 <div class="topbar-middle bg-secondary">
182                     <i class="lamp"></i>
183                     <select v-model="network" @change="networkToggle">
184                         <option value="mainnet">{{ $t('main.mainNet') }}</option>
185                         <option value="testnet">{{ $t('main.testNet') }}</option>
186                         <option value="solonet">{{ $t('main.soloNet') }}</option>
187                     </select>
188                 </div>
189             </div>
190             <div class="content">
191                 <div v-if="currentAccount.address!=undefined" class="amount color-white">
192                     <span class="alias color-grey">{{currentAccount.alias}}</span>
193                     <div class="token-amount">
194                         {{accountBalance}}
195                         <span class="asset">BTM</span>
196                     </div>
197                 </div>
198                 <div v-else>
199                   <p style="width: 250px; margin: 45px auto; text-align: center;">{{ $t('main.noAccount') }}</p>
200
201                 </div>
202             </div>
203             <div class="btn-send-transfer">
204                 <a v-if="currentAccount.address!=undefined" class="btn btn-primary btn-received" @click="showQrcode">{{ $t('main.receive') }}</a>
205                 <a v-if="currentAccount.address!=undefined" class="btn btn-primary btn-transfer" @click="transferOpen">{{ $t('main.send') }}</a>
206             </div>
207         </section>
208
209             <section class="transaction-title">
210                 <h3 class="bg-gray color-grey">{{ $t('main.record') }}</h3>
211             </section>
212             <section class="transactions">
213                  <div v-if="currentAccount.address!=undefined">
214                   <div v-if="transactions.length != 0">
215                       <vue-scroll @handle-scroll="handleScroll">
216                       <ul class="list">
217                           <li class="list-item" v-for="(transcation, index) in transactions" :key="index" @click="$router.push({name: 'transfer-info', params: {transcation: transcation, address: currentAccount.address}})">
218                               <div class="value">{{transcation.direct}} {{transcation.val.toFixed(2)}} BTM</div>
219                               <div>
220                                   <div v-if="transcation.is_confirmed" class="time">
221                                       <div v-if="transcation.block_timestamp === 0">
222                                           {{ $t('main.unconfirmed') }}
223                                       </div>
224                                       <div v-else>
225                                           {{transcation.block_timestamp | moment}}
226                                       </div>
227                                   </div>
228                                   <div v-else class="time">
229                                       <div v-if="transcation.submission_timestamp === 0">
230                                         {{ $t('main.unconfirmed') }}
231                                       </div>
232                                       <div v-else>
233                                         {{transcation.submission_timestamp | moment}}
234                                       </div>
235                                   </div>
236                                   <div class="addr color-grey">{{transcation.address}}</div>
237                               </div>
238                           </li>
239                       </ul>
240                   </vue-scroll>
241                   </div>
242                       <div v-else>
243                           <div class="bg-emptytx"></div>
244                           <div>
245                               <span class="color-lightgrey center-text no-record">{{$t('main.noRecord')}}</span>
246                           </div>
247                       </div>
248                   </div>
249                   <div v-else>
250                       <router-link :to="{name: 'menu-account-creation'}">
251                           <div class="bg-emptytx"></div>
252                           <div>
253                             <span class="color-lightgrey center-text no-record">{{$t('main.noRecord')}}</span>
254                           </div>
255                           <a class="btn btn-primary btn-creation">{{ $t('main.create') }}</a>
256                       </router-link>
257                   </div>
258             </section>
259
260         <!-- child page -->
261         <div class="mask" v-show="maskShow"></div>
262         <transition :enter-active-class="enterActive" :leave-active-class="leaveActive">
263             <router-view></router-view>
264         </transition>
265
266         <!-- modal -->
267         <Qrcode ref="qrcode"></Qrcode>
268     </div>
269 </template>
270
271 <script>
272 import ClipboardJS from "clipboard";
273 import Menu from "@/views/homeMenu";
274 import Qrcode from "@/views/qrcode";
275 import Transfer from "@/views/transfer";
276 import TxInfo from "@/views/transferDetail";
277 import address from "@/utils/address";
278 import account from "@/models/account";
279 import transaction from "@/models/transaction";
280 import { BTM } from "@/utils/constants";
281
282 const EnterActive = 'animated faster fadeInLeft';
283 const LeaveActive = 'animated faster fadeOutLeft';
284 export default {
285     name: "",
286     components: {
287         Qrcode,
288     },
289     data() {
290         return {
291             network: "mainnet",
292             clipboard: new ClipboardJS(".address-text"),
293             addressTitle: this.$t("main.copy"),
294             accounts: [],
295             currentAccount: {},
296             transactions: [],
297             maskShow: false,
298             start: 0,
299             limit: 10,
300             enterActive: EnterActive,
301             leaveActive: LeaveActive,
302         };
303     },
304     watch: {
305         '$route'(to, from) {
306             if (to.name.startsWith('menu')) {
307                 this.maskShow = true
308             } else if (from.name.startsWith('menu')) {
309                 this.maskShow = false
310             }
311
312             //account toggle by the list from menu
313             if (to.name == 'home' && to.params.selectedAccount != undefined) {
314                 this.currentAccount = to.params.selectedAccount
315                 this.refreshAccounts();
316             }
317
318             // remove transition for some page
319             this.enterActive = EnterActive
320             this.leaveActive = LeaveActive
321             if (to.name == 'transfer-confirm' || from.name == 'transfer-confirm') {
322                 this.enterActive = ''
323                 this.leaveActive = ''
324             }
325         },
326         currentAccount(newVal, oldVal) {
327             if (newVal.guid == undefined){
328               localStorage.currentAccount = {}
329               return;
330             }
331             localStorage.currentAccount = JSON.stringify(newVal);
332
333             this.refreshTransactions(newVal.guid, newVal.address).then(transactions => {
334                 this.transactions = transactions
335             });
336         },
337         'currentAccount.guid'(guid) {
338             if (guid == undefined) return;
339
340             this.refreshBalance(guid);
341         }
342     },
343     computed: {
344         shortAddress: function () {
345             return address.short(this.currentAccount.address)
346         },
347         accountBalance: function () {
348             return this.currentAccount.balance != 0 ? this.currentAccount.balance : '0.00'
349         }
350     },
351     methods: {
352         setupClipboard() {
353             this.clipboard.on("success", e => {
354                 this.$dialog.show({
355                     header: this.$t("dialog.header"),
356                     body: this.$t("dialog.copy.success")
357                 });
358             });
359             this.clipboard.on("error", e => {
360                 this.$dialog.show({
361                     header: this.$t("dialog.header"),
362                     body: this.$t("dialog.copy.fail")
363                 });
364             });
365         },
366         setupRefreshTimer() {
367             // todo refresh all accounts
368
369             setInterval(() => {
370                 this.refreshBalance(this.currentAccount.guid)
371             }, 10000)
372         },
373         setupNetwork() {
374             this.network = localStorage.bytomNet;
375             account.setupNet(this.network);
376         },
377         networkToggle: function (val) {
378             localStorage.bytomNet = this.network;
379             account.setupNet(this.network);
380             this.currentAccount = {}
381             this.refreshAccounts();
382         },
383         showQrcode: function () {
384             this.$refs.qrcode.open(this.currentAccount.address);
385         },
386         openMenu: function () {
387             this.$router.push({ name: 'menu', params: { accounts: this.accounts, selected: this.currentAccount } })
388         },
389         transferOpen: function () {
390             this.$router.push({ name: 'transfer', params: { account: this.currentAccount } })
391         },
392         handleScroll(vertical, horizontal, nativeEvent) {
393             if (vertical.process == 0) {
394                 this.start = 0;
395                 this.refreshTransactions(this.currentAccount.guid, this.currentAccount.address).then(transactions => {
396                     this.transactions = transactions
397                 });
398                 return;
399             }
400
401             if (vertical.process == 1) {
402                 this.start += this.limit;
403                 this.refreshTransactions(this.currentAccount.guid, this.currentAccount.address, this.start, this.limit).then(transactions => {
404                     transactions.forEach(transaction => {
405                         this.transactions.push(transaction);
406                     });
407                 });
408             }
409         },
410         refreshAccounts: function () {
411             account.list().then(accounts => {
412                 this.accounts = accounts;
413                 if (accounts.length == 0) {
414                     return;
415                 }
416
417                 if (this.currentAccount.guid == undefined) {
418                     this.currentAccount = accounts[0];
419                 }
420             })
421         },
422         refreshBalance: function (guid) {
423             account.balance(guid).then(balance => {
424                 this.currentAccount.balance = balance;
425                 this.currentAccount = Object.assign({}, this.currentAccount);
426             }).catch(error => {
427                 console.log(error);
428             });
429         },
430         refreshTransactions: function (guid, address, start, limit) {
431             return new Promise((resolve, reject) => {
432                 transaction.list(guid, address, start, limit).then(ret => {
433                     let transactions = ret.result.data;
434                     if (transactions == null) {
435                         return;
436                     }
437
438                     const formattedTx = this.transactionsFormat(transactions);
439                     console.log("formatTx", formattedTx);
440                     resolve(formattedTx)
441                 }).catch(error => {
442                     console.log(error);
443                     reject(error)
444                 });
445             })
446         },
447         transactionsFormat: function (transactions) {
448           const formattedTransactions = []
449           const assetID = BTM
450
451           transactions.forEach(transaction => {
452             const balanceObject = transaction.balances
453               .filter(b => b.asset === assetID);
454
455             if(balanceObject.length ===1 ){
456
457                 const inputAddresses = transaction.inputs
458                   .filter(input => input.asset === assetID && input.address !== this.currentAccount.address)
459                   .map(input => input.address)
460
461                 const outputAddresses = transaction.outputs
462                   .filter(output => output.asset === assetID && output.address !== this.currentAccount.address)
463                   .map(output => output.address)
464
465
466                 const val  = assetID===BTM ? Number(balanceObject[0].amount)/ 100000000 : Number(balanceObject[0].amount);
467
468                 if (val > 0) {
469                     transaction.direct = "+";
470                     transaction.address = address.short(inputAddresses.pop());
471                 } else {
472                     transaction.direct = "-";
473                     transaction.address = address.short(outputAddresses.pop());
474                 }
475
476                 transaction.val = Math.abs(val);
477                 transaction.fee = transaction.fee / 100000000;
478
479                 formattedTransactions.push(transaction);
480               }
481             });
482           return formattedTransactions;
483         },
484     },
485     mounted() {
486         this.currentAccount = JSON.parse(localStorage.currentAccount);
487         this.setupNetwork();
488         this.setupClipboard();
489         this.setupRefreshTimer();
490         this.refreshAccounts();
491     },
492     beforeDestroy() {
493         this.clipboard.destroy();
494     }
495 };
496 </script>