mirror of https://github.com/BTCPrivate/copay.git
Merge pull request #759 from cmgustavo/bug/01-amount-input
Bug/01 amount input
This commit is contained in:
commit
4467ae270f
|
@ -635,3 +635,9 @@ ul.pagination li.current a:hover, ul.pagination li.current a:focus {
|
||||||
color:white;
|
color:white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-note {
|
||||||
|
margin-top: -10px;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
14
index.html
14
index.html
|
@ -696,7 +696,6 @@
|
||||||
<div class="row collapse">
|
<div class="row collapse">
|
||||||
<label for="amount">Amount
|
<label for="amount">Amount
|
||||||
<small ng-hide="!sendForm.amount.$pristine">required</small>
|
<small ng-hide="!sendForm.amount.$pristine">required</small>
|
||||||
<i class="fi-arrow-up" title="Send all funds" ng-click="topAmount()"></i>
|
|
||||||
<small class="is-valid" ng-show="!sendForm.amount.$invalid && !sendForm.amount.$pristine">Valid</small>
|
<small class="is-valid" ng-show="!sendForm.amount.$invalid && !sendForm.amount.$pristine">Valid</small>
|
||||||
<small class="has-error" ng-show="sendForm.amount.$invalid && !sendForm.amount.$pristine && !notEnoughAmount">
|
<small class="has-error" ng-show="sendForm.amount.$invalid && !sendForm.amount.$pristine && !notEnoughAmount">
|
||||||
Not valid
|
Not valid
|
||||||
|
@ -706,9 +705,14 @@
|
||||||
<div class="small-9 columns">
|
<div class="small-9 columns">
|
||||||
<input type="number" id="amount" ng-disabled="loading"
|
<input type="number" id="amount" ng-disabled="loading"
|
||||||
name="amount" placeholder="Amount" ng-model="amount"
|
name="amount" placeholder="Amount" ng-model="amount"
|
||||||
min="1" max="10000000000" enough-amount required
|
min="0.0001" max="10000000000" enough-amount required
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
>
|
>
|
||||||
|
<a class="small input-note" title="Send all funds"
|
||||||
|
ng-show="$root.availableBalance > 0"
|
||||||
|
ng-click="topAmount(sendForm)">
|
||||||
|
Use all funds ({{getAvailableAmount()}} {{$root.unitName}})
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="small-3 columns">
|
<div class="small-3 columns">
|
||||||
<span class="postfix">{{$root.unitName}}</span>
|
<span class="postfix">{{$root.unitName}}</span>
|
||||||
|
@ -720,13 +724,13 @@
|
||||||
Total amount for this transaction:
|
Total amount for this transaction:
|
||||||
</small>
|
</small>
|
||||||
<div class="totalAmount">
|
<div class="totalAmount">
|
||||||
<b>{{amount + defaultFee |number}}</b> {{$root.unitName}}
|
<b>{{amount + defaultFee |number:4}}</b> {{$root.unitName}}
|
||||||
<small>
|
<small>
|
||||||
{{ ((amount + defaultFee) * unitToBtc) |number}} BTC
|
{{ ((amount + defaultFee) * unitToBtc) |number:4}} BTC
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
<small>
|
<small>
|
||||||
Including fee of {{defaultFee|number}} {{$root.unitName}}
|
Including fee of {{defaultFee |number:4}} {{$root.unitName}}
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -267,8 +267,12 @@ angular.module('copayApp.controllers').controller('SendController',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.topAmount = function() {
|
$scope.getAvailableAmount = function() {
|
||||||
var maxSat = ($rootScope.availableBalance * config.unitToSatoshi).toFixed(0) - bitcore.TransactionBuilder.FEE_PER_1000B_SAT;
|
return ((($rootScope.availableBalance * config.unitToSatoshi).toFixed(0) - bitcore.TransactionBuilder.FEE_PER_1000B_SAT) / config.unitToSatoshi);
|
||||||
$scope.amount = maxSat / config.unitToSatoshi;
|
};
|
||||||
|
|
||||||
|
$scope.topAmount = function(form) {
|
||||||
|
$scope.amount = $scope.getAvailableAmount();
|
||||||
|
form.amount.$pristine = false;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -40,12 +40,12 @@ angular.module('copayApp.directives')
|
||||||
.directive('enoughAmount', ['$rootScope',
|
.directive('enoughAmount', ['$rootScope',
|
||||||
function($rootScope) {
|
function($rootScope) {
|
||||||
var bitcore = require('bitcore');
|
var bitcore = require('bitcore');
|
||||||
var feeSat = bitcore.TransactionBuilder.FEE_PER_1000B_SAT;
|
var feeSat = Number(bitcore.TransactionBuilder.FEE_PER_1000B_SAT);
|
||||||
return {
|
return {
|
||||||
require: 'ngModel',
|
require: 'ngModel',
|
||||||
link: function(scope, element, attrs, ctrl) {
|
link: function(scope, element, attrs, ctrl) {
|
||||||
var val = function(value) {
|
var val = function(value) {
|
||||||
var availableBalanceNum = ($rootScope.availableBalance * config.unitToSatoshi).toFixed(0);
|
var availableBalanceNum = Number(($rootScope.availableBalance * config.unitToSatoshi).toFixed(0));
|
||||||
var vNum = Number((value * config.unitToSatoshi).toFixed(0)) + feeSat;
|
var vNum = Number((value * config.unitToSatoshi).toFixed(0)) + feeSat;
|
||||||
if (typeof vNum == "number" && vNum > 0) {
|
if (typeof vNum == "number" && vNum > 0) {
|
||||||
if (availableBalanceNum < vNum) {
|
if (availableBalanceNum < vNum) {
|
||||||
|
|
|
@ -282,10 +282,23 @@ describe("Unit: Controllers", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Send Controller', function() {
|
describe('Send Controller', function() {
|
||||||
var sendCtrl;
|
var sendCtrl, form;
|
||||||
beforeEach(inject(function($controller, $rootScope) {
|
beforeEach(inject(function($compile, $rootScope, $controller) {
|
||||||
scope = $rootScope.$new();
|
scope = $rootScope.$new();
|
||||||
$rootScope.availableBalance = 123456;
|
$rootScope.availableBalance = 123456;
|
||||||
|
|
||||||
|
var element = angular.element(
|
||||||
|
'<form name="form">' +
|
||||||
|
'<input type="number" id="amount" name="amount" placeholder="Amount" ng-model="amount" min="0.0001" max="10000000" enough-amount required>' +
|
||||||
|
'</form>'
|
||||||
|
);
|
||||||
|
scope.model = {
|
||||||
|
amount: null
|
||||||
|
};
|
||||||
|
$compile(element)(scope);
|
||||||
|
scope.$digest();
|
||||||
|
form = scope.form;
|
||||||
|
|
||||||
sendCtrl = $controller('SendController', {
|
sendCtrl = $controller('SendController', {
|
||||||
$scope: scope,
|
$scope: scope,
|
||||||
$modal: {},
|
$modal: {},
|
||||||
|
@ -296,8 +309,15 @@ describe("Unit: Controllers", function() {
|
||||||
expect(scope.isMobile).not.to.equal(null);
|
expect(scope.isMobile).not.to.equal(null);
|
||||||
});
|
});
|
||||||
it('should autotop balance correctly', function() {
|
it('should autotop balance correctly', function() {
|
||||||
scope.topAmount();
|
scope.topAmount(form);
|
||||||
|
form.amount.$setViewValue(123356);
|
||||||
expect(scope.amount).to.equal(123356);
|
expect(scope.amount).to.equal(123356);
|
||||||
|
expect(form.amount.$invalid).to.equal(false);
|
||||||
|
expect(form.amount.$pristine).to.equal(false);
|
||||||
|
});
|
||||||
|
it('should return available amount', function() {
|
||||||
|
var amount = scope.getAvailableAmount();
|
||||||
|
expect(amount).to.equal(123356);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,10 @@ describe("Unit: Testing Directives", function() {
|
||||||
|
|
||||||
beforeEach(module('copayApp.directives'));
|
beforeEach(module('copayApp.directives'));
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
config.unitToSatoshi = 100;
|
||||||
|
config.unitName = 'bits';
|
||||||
|
});
|
||||||
|
|
||||||
describe('Check config', function() {
|
describe('Check config', function() {
|
||||||
it('unit should be set to BITS in config.js', function() {
|
it('unit should be set to BITS in config.js', function() {
|
||||||
|
@ -43,6 +47,7 @@ describe("Unit: Testing Directives", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Validate Amount', function() {
|
describe('Validate Amount', function() {
|
||||||
|
describe('Unit: bits', function() {
|
||||||
beforeEach(inject(function($compile, $rootScope) {
|
beforeEach(inject(function($compile, $rootScope) {
|
||||||
$scope = $rootScope;
|
$scope = $rootScope;
|
||||||
$rootScope.availableBalance = 1000;
|
$rootScope.availableBalance = 1000;
|
||||||
|
@ -58,14 +63,13 @@ describe("Unit: Testing Directives", function() {
|
||||||
$scope.$digest();
|
$scope.$digest();
|
||||||
form = $scope.form;
|
form = $scope.form;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
it('should validate', function() {
|
it('should validate', function() {
|
||||||
form.amount.$setViewValue(100);
|
form.amount.$setViewValue(100);
|
||||||
expect(form.amount.$invalid).to.equal(false);
|
expect(form.amount.$invalid).to.equal(false);
|
||||||
form.amount.$setViewValue(900);
|
form.amount.$setViewValue(800);
|
||||||
expect(form.amount.$invalid).to.equal(false);
|
expect(form.amount.$invalid).to.equal(false);
|
||||||
|
form.amount.$setViewValue(900);
|
||||||
|
expect($scope.notEnoughAmount).to.equal(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not validate', function() {
|
it('should not validate', function() {
|
||||||
|
@ -77,9 +81,57 @@ describe("Unit: Testing Directives", function() {
|
||||||
expect(form.amount.$invalid).to.equal(true);
|
expect(form.amount.$invalid).to.equal(true);
|
||||||
form.amount.$setViewValue(1000);
|
form.amount.$setViewValue(1000);
|
||||||
expect(form.amount.$invalid).to.equal(true);
|
expect(form.amount.$invalid).to.equal(true);
|
||||||
|
form.amount.$setViewValue(901);
|
||||||
|
expect($scope.notEnoughAmount).to.equal(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Unit: BTC', function() {
|
||||||
|
beforeEach(inject(function($compile, $rootScope) {
|
||||||
|
config.unitToSatoshi = 100000000;
|
||||||
|
config.unitName = 'BTC';
|
||||||
|
$scope = $rootScope;
|
||||||
|
$rootScope.availableBalance = 0.04;
|
||||||
|
var element = angular.element(
|
||||||
|
'<form name="form">' +
|
||||||
|
'<input type="number" id="amount" name="amount" placeholder="Amount" ng-model="amount" min="0.0001" max="10000000" enough-amount required>' +
|
||||||
|
'</form>'
|
||||||
|
);
|
||||||
|
$scope.model = {
|
||||||
|
amount: null
|
||||||
|
};
|
||||||
|
$compile(element)($scope);
|
||||||
|
$scope.$digest();
|
||||||
|
form = $scope.form;
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should validate', function() {
|
||||||
|
form.amount.$setViewValue(0.01);
|
||||||
|
expect($scope.notEnoughAmount).to.equal(null);
|
||||||
|
expect(form.amount.$invalid).to.equal(false);
|
||||||
|
form.amount.$setViewValue(0.039);
|
||||||
|
expect($scope.notEnoughAmount).to.equal(null);
|
||||||
|
expect(form.amount.$invalid).to.equal(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not validate', function() {
|
||||||
|
form.amount.$setViewValue(0.03999);
|
||||||
|
expect($scope.notEnoughAmount).to.equal(true);
|
||||||
|
expect(form.amount.$invalid).to.equal(true);
|
||||||
|
form.amount.$setViewValue(0);
|
||||||
|
expect(form.amount.$invalid).to.equal(true);
|
||||||
|
form.amount.$setViewValue(0.0);
|
||||||
|
expect(form.amount.$invalid).to.equal(true);
|
||||||
|
form.amount.$setViewValue(0.05);
|
||||||
|
expect($scope.notEnoughAmount).to.equal(true);
|
||||||
|
expect(form.amount.$invalid).to.equal(true);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
describe('Contact directive', function() {
|
describe('Contact directive', function() {
|
||||||
var element1, element2;
|
var element1, element2;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,13 @@
|
||||||
//
|
//
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
config.unitToSatoshi = 100;
|
||||||
|
config.unitName = 'bits';
|
||||||
|
});
|
||||||
|
|
||||||
describe('Check config', function() {
|
describe('Check config', function() {
|
||||||
|
|
||||||
it('unit should be set to BITS in config.js', function() {
|
it('unit should be set to BITS in config.js', function() {
|
||||||
expect(config.unitToSatoshi).to.equal(100);
|
expect(config.unitToSatoshi).to.equal(100);
|
||||||
expect(config.unitName).to.equal('bits');
|
expect(config.unitName).to.equal('bits');
|
||||||
|
|
Loading…
Reference in New Issue