OSDN Git Service

update transfer page.
authorZhiting Lin <zlin035@uottawa.ca>
Tue, 11 Aug 2020 03:29:58 +0000 (11:29 +0800)
committerZhiting Lin <zlin035@uottawa.ca>
Tue, 11 Aug 2020 03:29:58 +0000 (11:29 +0800)
12 files changed:
src/assets/language/cn.js
src/assets/style.css
src/components/MenubarComponent.vue
src/components/backButton/button.vue
src/components/modal-passwd.vue
src/components/selection-page/page.vue
src/models/transaction.js
src/utils/Keychain.js
src/utils/address.js
src/views/sendTransaction/assetSelection.vue
src/views/sendTransaction/transfer.vue
src/views/viewBase.vue

index e2fb9f9..56a50e3 100644 (file)
@@ -87,7 +87,8 @@ const cn = {
     hide:'隐藏',
     viewAll:'展示全部',
     hideAll:'隐藏全部',
-    types:'交易类型'
+    types:'交易类型',
+    password:'请输入密码'
   },
   listAsset: {
     all:'全部',
@@ -238,6 +239,8 @@ const cn = {
     BTM0002:'助记词验证失败,请输入正确助记词。',
     BTM0003:'请选择Keystore文件。',
     BTM0004:'请输入Keystore。',
+    BTM0005:'输入数量大于可用余额。',
+    BTM0006:'输入有效的地址格式。',
   },
   successMsg:{
     createWallet:{
index fe632e3..7a834be 100644 (file)
@@ -429,7 +429,7 @@ hr {
   bottom: 0;
   opacity: 1;
   visibility: visible;
-  background-color: rgba(0, 0, 0, 0.7);
+  background-color: rgba(0, 0, 0, 0.4);
 }
 
 .menu-title {
@@ -547,6 +547,20 @@ hr {
   border: none;
 }
 
+.btn-outlined
+{
+  border: 1px solid #D6D6D6;
+  background: white;
+  color: #D6D6D6;
+}
+
+.btn-outlined:active,
+.btn-outlined:hover,
+.btn-outlined:focus {
+  color: #ffffff;
+  background-color: #D6D6D6;
+}
+
 .btn-warning {
   background-color: #E60000;
 }
index 958b982..ca80a47 100644 (file)
@@ -31,7 +31,8 @@
                 RouteNames.HOME,
                 RouteNames.ASSET,
                 RouteNames.TRANSFER,
-                RouteNames.RECEIVE
+                RouteNames.RECEIVE,
+                RouteNames.ASSET_SELECTION
               ]
               switch(name){
                 case 'HOME':{
index 91cac80..5481277 100644 (file)
@@ -8,12 +8,19 @@
 export default {
     props: {
       des:null,
-      small:false
+      small:false,
+      back:{
+        type: Function
+      }
     },
     methods: {
       goBack:function () {
-        this.des?
-          this.$router.push({name: this.des}): this.$router.go(-1)
+        if(this.back){
+          this.back()
+        }else{
+          this.des?
+            this.$router.push({name: this.des}): this.$router.go(-1)
+        }
       }
     }
 };
index ce9a61b..1732488 100644 (file)
@@ -1,31 +1,29 @@
 <style scoped>
 .mask {
     z-index: 3 !important;
-    top: 60px !important;
 }
 
 .confirm {
-    padding: 10px 20px;
-    position: fixed;
-    width: 310px;
+    padding: 20px 16px;
+    position: absolute;
+    width: 260px;
     left: 0;
     bottom: 0;
     right: 0;
     z-index: 4;
+    margin: auto;
+    top: 0;
+    height: 131px;
+    border-radius: 8px;
 }
 
 .btn-inline {
     display: flex;
     padding: 0;
+    justify-content: space-between;
 }
 .btn-inline .btn {
-    margin: 10px 15px;
-}
-.form-item-content-en {
-    margin-left: 145px;
-}
-.form-item-content-cn {
-    margin-left: 85px;
+    width:47%;
 }
 </style>
 
     <div>
         <section v-show="show" class="mask"></section>
         <transition name="page-transfer" <!-- enter-active-class="animated slideInUp faster" leave-active-class="animated slideOutDown faster"> -->
-            <div v-show="show" class="confirm form bg-gray">
+            <div v-show="show" class="confirm form bg-white">
                 <div class="form-item">
-                    <label class="form-item-label">{{ $t('transfer.confirmPassword') }}</label>
-                    <div :class="passwdStyle">
-                        <input type="password" v-model="passwd" autofocus>
+                    <div class="form-item-content">
+                        <input type="password" v-model="passwd" :placeholder="$t('transfer.password')" autofocus>
                     </div>
                 </div>
                 <div class="btn-group btn-inline">
-                    <div class="btn bg-green" @click="confirm">{{ $t('welcome.confirm') }}</div>
-                    <div class="btn bg-red" @click="close">{{ $t('welcome.cancel') }}</div>
+                    <div class="btn btn-outlined" @click="close">{{ $t('welcome.cancel') }}</div>
+                    <div :class="['btn', netType ==='vapor'?'btn-vapor':'btn-bytom']"  @click="confirm">{{ $t('welcome.confirm') }}</div>
                 </div>
             </div>
         </transition>
@@ -53,8 +50,6 @@
 import { getLanguage } from "@/assets/language"
 import { mapGetters } from 'vuex'
 
-const CLASS_CN = "form-item-content form-item-content-cn";
-const CLASS_EN = "form-item-content form-item-content-en"
 export default {
     data() {
         return {
@@ -69,16 +64,9 @@ export default {
         }
     },
     computed: {
-        passwdStyle: function () {
-            if (this.i18n == "cn") {
-                return CLASS_CN;
-            } else if (this.i18n == "en") {
-                return CLASS_EN;
-            }
-            return CLASS_CN;
-        },
         ...mapGetters([
-          'language'
+          'language',
+          'netType'
         ])
     },
     methods: {
@@ -92,9 +80,9 @@ export default {
         },
         confirm() {
             if (this.passwd == "") {
-                this.$dialog.show({
-                    body: this.$t("transfer.emptyPassword")
-                });
+                this.$toast.error(
+                    this.$t("transfer.emptyPassword")
+                );
                 return;
             }
 
index 1a14fa9..81adaf8 100644 (file)
@@ -3,7 +3,7 @@
         <label class="select-item font-bold" v-for="option in options"  :for="option.label">
           {{option.label}}
           <input type="radio" :id="option.label" :name="option.label" :value="option.value" @change="onChange" :checked="(option.value == value)">
-        </label><br>
+        </label>
     </div>
 </template>
 
@@ -39,8 +39,11 @@ export default {
   align-items: center;
   justify-content: space-between;
   padding: 16px;
-  margin-bottom: 20px;
   color: rgba(0, 0, 0, 0.88);
   font-size:15px;
 }
+.select-item:not(:last-child){
+  margin-bottom: 20px;
+
+}
 </style>
index b4582d9..e3a2588 100644 (file)
@@ -35,7 +35,7 @@ transaction.asset = function(asset_id) {
 transaction.build = function(address, to, asset, amount, fee, confirmations) {
   let retPromise = new Promise((resolve, reject) => {
     bytom.transaction
-      .buildPayment(address, to, asset, amount.toString(), fee, confirmations)
+      .buildPayment(address, to, asset, amount.toString(), confirmations)
       .then(res => {
         resolve(res);
       })
@@ -134,35 +134,58 @@ transaction.decodeTransaction = function(rawTx) {
   return retPromise;
 };
 
-transaction.transfer = function(guid, transaction, password, address, context) {
+transaction.transfer = function(transaction, password, address, context) {
   let retPromise = new Promise((resolve, reject) => {
-      signTx(
-        guid,
-        JSON.stringify(snakeize(transaction)),
-        password,
-        context
-      )
-      .then(ret => {
-        bytom.transaction
-          .submitPayment(address, ret.raw_transaction, ret.signatures)
-          .then(res3 => {
-            const object ={
-              transactionHash: res3.txHash
-            }
-            resolve(object);
-          })
-          .catch(error => {
-            reject(error);
-          });
+
+    const {to, asset, amount, confirmations} = transaction
+    bytom.transaction
+      .buildPayment(address, to, asset, amount.toString(), confirmations)
+      .then(result => {
+        Promise.all(result.map( (data) => 
+          signSubmit( data, password, address, context)))
+            .then((ret )=>{
+              resolve(ret)
+            })
+            .catch(error => {
+              throw error
+            });
       })
       .catch(error => {
         reject(error);
       });
-  });
+  })
 
   return retPromise;
 };
 
+function signSubmit (txObject, password, address, context) {
+  let retPromise = new Promise((resolve, reject) => {
+        signTx(
+          address,
+          JSON.stringify(snakeize(txObject)),
+          password,
+          context
+        )
+          .then(ret => {
+            bytom.transaction
+              .submitPayment(address, ret.raw_transaction, ret.signatures)
+              .then(res3 => {
+                const object = {
+                  transactionHash: res3.txHash
+                }
+                resolve(object);
+              })
+              .catch(error => {
+                throw error
+              });
+          })
+          .catch(error => {
+            reject(error);
+          });
+      });
+  return retPromise;
+};
+
 
 transaction.signMessage = function(message, password, address) {
   return bytom.keys.signMessage(message, password,address);
@@ -203,21 +226,23 @@ transaction.advancedTransfer = function(guid, transaction, password, arrayData,
 
 
 
-function signTx(guid, transaction, password, context){
-  return bytom.accounts.getAccountXpubById(guid).then((xpub)=>{
-    const keyArray = context.bytom.keychain.findIdentity(xpub);
-    if(!keyArray){
-      throw 'xpub not found'
-    }else{
-      const key = keyArray.key
-      return bytom.transaction
-        ._signTransaction(
-          transaction,
-          password,
-          key
-        )
-    }
-  })
+function signTx(address, transaction, password, context){
+  const keyArray = context.bytom.keychain.findByAddress(address);
+  if(!keyArray){
+    throw 'Account not found.'
+  }else{
+    const key = JSON.stringify(keyArray.keystore)
+    return bytom.transaction
+      ._signTransaction(
+        transaction,
+        password,
+        key
+      )
+  }
+}
+
+transaction.estimateFee = function(address, asset_amounts, confirmations){
+  return bytom.transaction.estimateFee(address, asset_amounts, confirmations)
 }
 
 export default transaction;
index 4398e80..21192b9 100644 (file)
@@ -13,6 +13,8 @@ export default class Keychain {
 
   findIdentity(publicKey){ return Object.values(this.pairs).find(id => id.xpub === publicKey); }
   findByGuid(guid){ return Object.values(this.pairs).find(id => id.guid === guid); }
+  findByAddress(address){ return Object.values(this.pairs).find(id => id.address === address || id.vpAddress=== address); }
+
 
   removeUnverifyIdentity(){
     const pairObject = Object.values(this.pairs).filter(id => !id.vMnemonic );
index 9a866e4..e32a437 100644 (file)
@@ -12,4 +12,14 @@ export default class address {
     let endSome = rawAddress.substr(rawAddress.length - length, length)
     return startSome + '...' + endSome
   }
+
+  static isValid(address, netType) {
+    if (netType == 'vapor') {
+      const vpArray = ['vp', 'tp', 'sp']
+      return vpArray.includes( address.substring(0,2) )
+    }else{
+      const bmArray = ['bm', 'tm', 'sm']
+      return bmArray.includes( address.substring(0,2) )
+    }
+  }
 }
index b991cac..20ea8d0 100644 (file)
@@ -7,6 +7,17 @@
       font-size: 20px;
     }
   }
+  .button-section{
+    position: fixed;
+    width: calc( 100% - 120px);
+    bottom: 0;
+    padding-bottom: 30px;
+  }
+
+  .selction-section{
+    height: calc( 100% - 149px );
+    overflow: scroll;
+  }
 
 </style>
 
             <div class="welcome-title">{{ $t('transfer.asset')}}</div>
           </h1>
         </section>
-        <section>
+        <section class="selction-section">
           <SelectionPage :value="asset" :options="assets" :onChange="assetToggle"></SelectionPage>
         </section>
-        <section>
+        <section class="button-section">
           <button :class="['btn', netType ==='vapor'?'btn-vapor':'btn-bytom']" @click="setAsset(asset)">
             {{$t('common.confirm')}}
           </button>
@@ -53,6 +64,9 @@ export default {
         }
 
       },
+      ...mapState([
+        'currentAsset'
+      ]),
         ...mapGetters([
           'currentAccount',
           'netType'
@@ -62,15 +76,26 @@ export default {
       assetToggle: function(event){
         this.asset = event.target.value
       },
-      ...mapActions([
-        Actions.SET_CURRENT_ASSET,
-      ]),
       setAsset(asset){
-        this[Actions.SET_CURRENT_ASSET](asset)
+        let balance
+        if(this.netType === 'vapor'){
+          balance = this.currentAccount.vpBalances.find(b => b.asset.symbol ==asset)
+        }else{
+          balance = this.currentAccount.balances.find(b => b.asset.symbol ==asset)
+        }
+        if(balance){
+            this[Actions.SET_CURRENT_ASSET](balance.asset)
+          }
         this.$router.go(-1)
-      }
+      },
+      ...mapActions([
+        Actions.SET_CURRENT_ASSET,
+      ])
     },
     mounted() {
+      if(this.currentAsset){
+        this.asset = this.currentAsset.symbol
+      }
     },
   };
 </script>
index a81acd2..38a121b 100644 (file)
 <style lang="scss" scoped>
-.header{
-    display: flex;
-    margin-bottom: 20px;
-    h1{
-      margin-left: 12px;
-      font-size: 20px;
-    }
-  }
-.balance {
-  width: 280px;
-  height: 40px;
-    margin: 20px;
-    padding: 20px;
+.header {
   display: flex;
+  margin-bottom: 20px;
+  h1 {
+    margin-left: 12px;
+    font-size: 20px;
+  }
 }
-.balance .token-icon {
-    height: 38px;
-    width: 38px;
-    margin-right: 5px;
-}
-.balance .token-amount {
-    display: inline-block;
-}
-.balance .token-amount .asset {
-    font-size: 18px;
-    margin-left: 2px;
-    text-transform: uppercase;
+.form{
+  padding: 16px;
 }
-.form-container{
-  margin: 20px;
+.form-item-content input, input.form-item-content {
+    background: none;
+    border-radius: 0;
+    border-bottom: 0.5px solid #EBEBEB;
+    padding: 0;
+    width:100%
+  }
+
+.form-item-content input:focus,
+input.form-item-content:focus,
+input.form-item-content:active
+{
+  border: 0;
+  border-bottom: 0.5px solid #004EE4;
+
 }
-.form {
-    margin-bottom: 20px;
-    padding: 10px 15px;
-    border-radius:4px;
+
+.currency{
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-top: 16px;
+    padding-bottom: 17px;
+    border-bottom: 0.5px solid #EBEBEB;
+      cursor: pointer;
+
+
+    .symbol{
+      display:flex;
+      font-weight: 600;
+      font-size: 15px;
+    align-items: center;
+    }
+
+    .assetId{
+      font-size:13px;
+      align-items: center;
+      display: flex;
+    }
 }
-.form-container .btn{
-    height: 48px;
-    bottom: 20px;
+
+.hint{
+    font-size: 13px;
     position: absolute;
-    width: 320px;
+    right: 5px;
+    display: flex;
+    align-items:center;
 }
-  .small{
-    font-size: 12px;
+
+.amount-input{
+  display: flex;
+  align-items: center;
+  input{
+    font-size: 28px;
+    font-weight: 600;
   }
-.transfer-header{
-  background-image: url("../../assets/img/backgroundHead/transfer.svg");
-  background-size: 320px 80px;
-}
-.wallet{
-  width: 40px;
-  height: 40px;
-  background: rgba(255,255,255,0.1);
-  border-radius: 50%;
-  color: white;
-  margin-right: 20px;
-  line-height: 40px;
-  text-align: center;
 }
 
-.asset-option{
-  font-size: 15px;
-  text-transform: uppercase;
+.form{
+  margin-bottom: 20px;
+  label{
+    color: rgba(0, 0, 0, 0.36);
+  }
 }
 
-.asset-option  .asset-id{
-  font-size: 13px;
-}
+.tx-fee{
+  font-size: 12px;
+  display: flex;
 
-.v-select{
-  height: 50px;
-  width: 100%;
-  background: rgba(247,247,247,1);
-  font-size: 14px;
-  margin: auto;
-  border-bottom: 1px solid #E0E0E0;
+  div{
+    margin-left: 7px;
+    color: #5C5C5C;
+  }
 }
 
+.max{
+  padding: 2px 12px;
+  background: #EEF4FF;
+  margin-right: 8px;
+  border-radius: 15px;
+  color: #004EE4;
+  font-size: 12px;
+  cursor: pointer;
+}
 </style>
 
 <template>
     <div class="warp-child bg-grey">
       <section class="header">
-        <BackButton :small="true" :des="'home'"/>
+        <BackButton :small="true" :back="close"/>
         <h1 class="color-black">
           <div class="welcome-title">{{ $t('main.send') }}</div>
         </h1>
       </section>
 
-        <section class="bg-shadow-white ">
-          <div class="wallet">
-            <i class="iconfont icon-wallet"></i>
-          </div>
-          <div>
-            <div class="token-amount">
-                {{accountBalance}}
-                <span v-if="selectAsset.symbol" class="asset">{{selectAsset.symbol}}</span>
-            </div>
-            <div class="small color-grey">
-              {{currentAccount.alias}}
-            </div>
-          </div>
-          
-          <div class="form bg-white">
-              <div class="form-item">
-                  <label class="form-item-label">{{ $t('transfer.asset') }}</label>
-                  <div class="form-item-content" >
-                    <v-select :options="assets" v-bind:colorBlack="true" :clearable="false" :value="selectAsset" :onChange="assetChange" label="assetId">
-                      <template slot="selected-option" slot-scope="asset">
-                        <div class="asset-option">
-                          <div>{{asset.symbol || 'Asset'}}</div>
-                          <div  class="color-grey asset-id">{{shortAddress(asset.assetId)}}</div>
-                        </div>
-                      </template>
-                      <template slot="option" slot-scope="asset">
-                        <div class="asset-option">
-                          <div>{{asset.symbol || 'Asset'}}</div>
-                          <div class="color-grey  asset-id">{{shortAddress(asset.assetId)}}</div>
-                        </div>
-                      </template>
-                    </v-select>
+      <section class="bg-shadow-white form">
+
+        <div>
+            <div class="form-item">
+                <label class="form-item-label">{{ $t('transfer.asset') }}</label>
+                <div class="form-item-content currency"  @click="$router.push({ name: 'asset-selection' })">
+                  <div class="symbol color-black">
+                    <img :src="img(unit)" alt="" class="c-icon">
+
+                    <div class="uppercase">
+                      {{ unit }}
+                    </div>
+
                   </div>
-              </div>
-              <div class="form-item">
-                <label class="form-item-label">{{ $t('transfer.address') }}</label>
-                <input class="form-item-content"  type="text" v-model="transaction.to">
-              </div>
-              <div class="form-item">
-                  <label class="form-item-label" for="tx-amount">
-                    {{ $t('transfer.quantity') }}
-
-                    <small class="float-right" style="margin-right: 8px;">{{formatCurrency(transaction.cost||0)}}</small>
-                  </label>
-                  <div class="form-item-content" style=" display: flex;">
-                    <input type="number" id="tx-amount" v-model="transaction.amount" placeholder="0" @keypress="limitAmount">
-                      <span class="color-grey" style="font-size: 15px;position: absolute;right: 0;text-transform: uppercase;">{{unit}}</span>
+
+                  <div class=" text-align-right">
+                    <div class="color-grey-36 uppercase assetId">{{ shortAddress(selectAsset.assetId) }} <i class="iconfont iconarrow_1"></i></div>
                   </div>
-              </div>
-              <div class="form-item">
-                  <label class="form-item-label">{{ $t('transfer.fee') }}</label>
-                  <div class="form-item-content" >
-                      <!--<v-select :clearable="false" v-model="fee" style="height: 32px;" :options="feeTypeOptions"></v-select>-->
-                    <input type="text"  v-model="fee" disabled >
+
+
+                </div>
+            </div>
+            <div class="form-item">
+              <label class="form-item-label">{{ $t('transfer.address') }}</label>
+              <input class="form-item-content"
+              :placeholder="netType=='vapor'? $t('transfer.vaporAddress'): $t('transfer.bytomAddress')"
+              type="text"
+              id="to"
+              name="to"
+              ref="to"
+              v-model="$v.transaction.to.$model"
+              >
+            </div>
+            <div class="form-item">
+                <label class="form-item-label" for="tx-amount">
+                  {{ unit+$t('transfer.quantity') }}
+
+                  <small class="float-right color-grey-36" style="margin-right: 8px; margin-top: 8px;">
+                    {{ `${$t('transfer.available')} ${currentBalance} ${unit}` }}
+
+                  </small>
+                </label>
+                <div class="form-item-content amount-input">
+                  <input
+                    type="number"
+                    id="tx-amount"
+                    placeholder="0"
+                    name="amount"
+                    ref="amount"
+                    v-model="$v.transaction.amount.$model"
+                    @keypress="limitAmount"
+                  >
+                  <div class="hint">
+                    <div class="max" @click="max()">Max</div>
+                    <span class="color-grey-36">≈ {{formatCurrency(transaction.cost||0)}}</span>
                   </div>
-              </div>
-          </div>
-          <a class="btn btn-primary" @click="send">{{ $t('transfer.send') }}</a>
-        </section>
+
+                </div>
+            </div>
+
+            <div class="tx-fee">
+                <label >{{ $t('transfer.fee') }}</label>
+                <div>{{ transaction.fee }} BTM</div>
+            </div>
+        </div>
+      </section>
+      <section>
+          <a :class="['btn', netType ==='vapor'?'btn-vapor':'btn-bytom']" @click="validate">{{ $t('transfer.send') }}</a>
+      </section>
+
+      <modal-passwd ref="modalPasswd" @confirm="send"></modal-passwd>
     </div>
 </template>
 
 <script>
   import address from "@/utils/address";
-  import account from "@/models/account";
 import transaction from "@/models/transaction";
 import getLang from "@/assets/language/sdk";
 import Confirm from "./transferConfirm";
 import { BTM } from "@/utils/constants";
-  import { Number as Num } from "@/utils/Number"
+import { Number as Num } from "@/utils/Number"
 import { mapActions, mapGetters, mapState } from 'vuex'
 import * as Actions from '@/store/constants';
-  import _ from 'lodash'
+import _ from 'lodash'
+import { required } from "vuelidate/lib/validators";
+import BigNumber from "bignumber.js"
+
 
   const currencyInPrice = {
     in_cny: 'cnyPrice',
@@ -177,28 +208,35 @@ export default {
     },
     data() {
         return {
-            selectAsset: {
-                assetId: BTM,
-                symbol: "BTM",
-                decimals:8
-            },
             show: false,
-            address: null,
+            address: '',
             guid: null,
             account: {},
-            accountBalance: 0.00,
-            fee: this.$t("transfer.feeType"),
-            feeTypeOptions: [this.$t("transfer.feeType")],
             transaction: {
                 to: "",
                 asset: BTM,
                 amount: "",
-                fee: null,
+                fee: '0.00000000',
                 cost: "",
                 confirmations: 1
+            },
+            selectAsset:{
+              assetId: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+              name: "Bytom",
+              symbol: "BTM"
             }
         };
     },
+    validations: {
+      transaction: {
+        to:{
+          required
+        },
+        amount:{
+          required
+        }
+      }
+  },
     computed: {
         assets(){
           if(this.netType === 'vapor'){
@@ -215,11 +253,25 @@ export default {
             }
           }
         },
+        currentBalance(){
+          const assetId = this.selectAsset.assetId
+          let balances
+
+          if(this.netType === 'vapor'){
+            balances = this.currentAccount.vpBalances
+          }else{
+            balances = this.currentAccount.balances
+          }
+
+          const balance = balances.find(b => b.asset.assetId === assetId)
+          return balance? balance.availableBalance:0;
+        },
         unit() {
-            return this.selectAsset.symbol;
+          return this.selectAsset.symbol;
         },
       ...mapState([
-        'bytom'
+        'bytom',
+        'currentAsset'
       ]),
       ...mapGetters([
         'currentAccount',
@@ -232,26 +284,39 @@ export default {
         "transaction.amount": function (newAmount) {
             const singlePrice = this.selectAsset[currencyInPrice[this.currency]]||this.selectAsset[this.currency]||0
             this.transaction.cost = Number( singlePrice * newAmount).toFixed(2);
+
+            if(newAmount){
+              this.estimateFee()
+            }else{
+              this.transaction.fee = '0.00000000'
+            }
         },
         account: function (newAccount) {
+            if (newAccount.guid == undefined){
+                return;
+              }
+
             this.guid = newAccount.guid;
             this.address = this.netType === 'vapor'?  newAccount.vpAddress: newAccount.address;
-        },
-        address: function (newAddress) {
-            account.balance(newAddress).then(obj => {
-              const balances = obj.balances
-              let balance = 0.00
-              if(balances.length >0 ) {
-                const balanceObject = balances.filter(b => b.asset.assetId === this.selectAsset.assetId)[0]
-                balance = Num.formatNue(balanceObject.balance, balanceObject.decimals)
-              }
-                this.accountBalance = balance;
-            }).catch(error => {
-                console.log(error);
-            });
         }
     },
     methods: {
+        estimateFee: function(){
+          const asset_amount={}
+          asset_amount[this.selectAsset.assetId] = this.transaction.amount || 0;
+
+          transaction.estimateFee(this.address, asset_amount).then( (resp) =>{
+            this.transaction.fee = resp.fee
+          })
+        },
+        img:function (symbol) {
+          const _symbol = symbol.toLowerCase();
+          if(this.netType === 'vapor'){
+            return `https://cdn.blockmeta.com/resources/logo/vapor/${_symbol}.png`
+          }else{
+            return `https://cdn.blockmeta.com/resources/logo/bytom/${_symbol}.png`
+          }
+        },
         shortAddress: function (add) {
           return address.short(add)
         },
@@ -260,75 +325,98 @@ export default {
         },
         limitAmount ($event) {
           // restrict to 2 decimal places
+          const n = new BigNumber(this.transaction.amount)
+
           if(this.transaction.amount!=null && this.transaction.amount.indexOf(".")>-1 && (this.transaction.amount.split('.')[1].length > (this.selectAsset.decimals-1))){
             $event.preventDefault();
           }
         },
-        assetChange: function (val) {
-          console.log(val)
-          if(val.assetId !== this.selectAsset.assetId){
-            this.transaction.asset = val.assetId;
-            const balances = this.netType === 'vapor'?this.currentAccount.vpBalances:this.currentAccount.balances
-            let balance = 0.00
-            if(balances.length >0 ) {
-              console.log(balances)
-              const balanceObject = balances.filter(b => b.asset.assetId === val.assetId)[0]
-              balance = balanceObject.balance
-            }
-            this.accountBalance = balance;
-
-            transaction.asset(val.assetId).then(ret => {
-              console.log(ret)
-              this.selectAsset = Object.assign(ret,val)
-              this.transaction.cost = Number(ret[currencyInPrice[this.currency]] * this.transaction.amount).toFixed(2);
-            });
-          }
-        },
         close: function () {
-            this.$router.go(-1)
+            this.$router.push({name: 'home'});
+            this[Actions.SET_CURRENT_ASSET](undefined)
+
             this.transaction.to = "";
             this.transaction.amount = "";
             if(this.$route.query.type == 'popup'){
                window.close();
             }
         },
-        send: function () {
-            if (this.transaction.to == "") {
-                this.$dialog.show({
-                    body: this.$t("transfer.emptyTo")
-                });
-                return;
-            }
+        max: function () {
+            this.transaction.amount = this.currentBalance;
+        },
+        validate: function () {
+          this.$v.$touch();
+          if (this.$v.$invalid) {
+            const transaction = this.$v.transaction
+            for (let key in Object.keys(transaction)) {
+              const input = Object.keys(transaction)[key];
+              if (input.includes("$")) return false;
 
-            if (this.transaction.amount <= 0) {
-                this.$dialog.show({
-                    body: this.$t("transfer.noneBTM")
-                });
+              if (transaction[input].$error) {
+                switch(input){
+                  case 'to':
+                    this.$toast.error(
+                      this.$t("transfer.emptyTo")
+                    );
+                    break;
+                  case 'amount':
+                    this.$toast.error(
+                      this.$t("transfer.noneBTM")
+                    );
+                    break;
+                }
+                this.$refs[input].focus();
+                break;
+              }
+            }
+          } else {
+            const n = new BigNumber(this.transaction.amount)
+            const to  = this.transaction.to
+            if(!address.isValid(to, this.netType)){
+                this.$toast.error(
+                    this.$t("error.BTM0006")
+                );
+                this.$refs['to'].focus();
+                return
+            }
+            else if (n.gt(this.currentBalance)) {
+                this.$toast.error(
+                    this.$t("error.BTM0005")
+                );
+                this.$refs['amount'].focus();
                 return;
             }
 
+            this.$refs.modalPasswd.open();
+        }
+      },
+      send: function (password) {
+
             let loader = this.$loading.show({
                 // Optional parameters
                 container: null,
                 canCancel: true,
                 onCancel: this.onCancel
             });
-            transaction.build(this.address, this.transaction.to, this.transaction.asset, this.transaction.amount, this.transaction.fee, this.transaction.confirmations).then(result => {
-                console.log(result)
+
+            this.transaction.asset = this.selectAsset.assetId;
+            transaction.transfer(this.transaction, password, this.address, this).then(result => {
                 loader.hide();
-                if(!this.transaction.fee){
-                    this.transaction.fee = Number( _.sumBy(result, 'tx.fee'));
-                }
-                this.$router.push({ name: 'transfer-confirm', params: { account: this.account, transaction: this.transaction, rawData: result, assetAlias: this.selectAsset.symbol, type: this.$route.query.type } })
+                this.$router.push('/')
+
             }).catch(error => {
                 loader.hide();
-                this.$dialog.show({
-                    body: getLang(error.message)
-                });
+                this.$toast.error(
+                   getLang(error.message)
+                );
             });
-        }
+      },
+      ...mapActions([
+        Actions.SET_CURRENT_ASSET,
+      ])
     }, mounted() {
         //detect injection
+        let currentAssetId
         if(this.$route.query.type === 'popup'){
           if (this.$route.query.from != undefined) {
               this.address = this.$route.query.from
@@ -337,7 +425,7 @@ export default {
           }
 
           if (this.$route.query.asset != undefined) {
-            const currentAssetId = this.$route.query.asset
+            currentAssetId = this.$route.query.asset
 
             this.transaction.asset= currentAssetId
 
@@ -359,15 +447,20 @@ export default {
         }else{
           this.account = this.currentAccount
 
-          const currentAsset = this.netType === 'vapor'? this.currentAccount.vpBalances[0]: this.currentAccount.balances[0]
+          const currentAsset = this.currentAsset || this.selectAsset
+          currentAssetId = currentAsset.assetId
 
-          if(currentAsset){
-            transaction.asset(currentAsset.asset.assetId).then(ret => {
-                this.selectAsset = Object.assign(ret,currentAsset)
-            });
-          }
         }
 
+        const that = this
+
+        transaction.asset(currentAssetId).then(ret => {
+            that.selectAsset = ret
+            if(that.transaction.amount){
+              that.transaction.cost = Number(ret[currencyInPrice[that.currency]] * that.transaction.amount).toFixed(2);
+            }
+          });
+
     }
 };
 </script>
index 3187fdb..729c4af 100644 (file)
@@ -33,7 +33,6 @@
         <menu-bar></menu-bar>
         <router-view></router-view>
         <success></success>
-        <modal-passwd></modal-passwd>
     </section>
 </template>