fix conflicts

This commit is contained in:
Matias Alejo Garcia 2014-06-24 13:02:25 -03:00
commit f1257d054c
49 changed files with 1013 additions and 753 deletions

View File

@ -15,7 +15,7 @@ html, body {height: 100%;}
#main {
overflow:auto;
padding-bottom: 91px;} /* must be same height as the footer */
padding-bottom: 80px;} /* must be same height as the footer */
.main-home {
padding-bottom: 28px !important;
@ -37,9 +37,8 @@ html, body {height: 100%;}
#footer {
position: fixed;
margin-top: -96px; /* negative value of footer height */
height: 80px;
margin-top: -80px; /* negative value of footer height */
height: 70px;
clear:both;
padding: 5px 2rem;
bottom: 0;
@ -65,7 +64,6 @@ html, body {height: 100%;}
.logo {
display: block;
height: 51px;
margin: 0 auto;
}
.top-bar-section li:not(.has-form) a:not(.button) {
@ -173,12 +171,6 @@ h3 {
border-right: 2px dashed #E3E3E3;
}
@media (max-width: 640px) {
.line-dashed-v {
border: none;
}
}
.line-dashed-h {
margin: 1rem 0;
border-bottom: 2px dashed #E3E3E3;
@ -238,28 +230,13 @@ input[type=number]::-webkit-outer-spin-button {
line-height: inherit;
}
@media (max-width: 641px) {
.hide_menu {
display: none;
}
.show_menu {
display: block;
}
.top-bar-section ul li {
width: 100%;
}
}
@media (max-width: 750px) {
.top-bar-section ul li>a {
font-size: 70%;
}
}
.new-address {
width: 220px;
}
.transactions button, .transactions .button {
padding: 0.5rem 2rem;
}
hr { margin: 2.25rem 0;}
@ -406,10 +383,13 @@ hr { margin: 2.25rem 0;}
margin-right: 10px;
margin-bottom: 10px;
border: 3px solid #eee;
opacity: 0.3;
border-radius: 0.3rem;
}
.box-setup-copay-required {
border: 3px solid green;
border: 3px solid #1ABC9C;
opacity: 1;
}
.tx-copayers {
@ -655,52 +635,3 @@ ul.pagination li.current a:hover, ul.pagination li.current a:focus {
color:white;
}
@media only screen and (max-width: 40em) {
#main, .header-content {
font-size: 80%;
line-height: 140%;
}
.top-bar {
background: #1ABC9C;
}
.header-content {
padding: 0.3rem 0rem 1rem 0.4rem;
}
.logo {
background-size: 90px 44px !important;
float: left;
margin-top: 0.7rem;
width: 130px;
}
.header-content .small-9 {
text-align: right !important;
}
.header-content .line-dashed-v {
border: none !important;
}
.box-backup {
margin: 0.6rem 0;
}
#footer {
font-size: 80%;
padding: 0.2rem 0.5rem;
}
.box-status {
height: 71px;
}
.box-copayers figure {
height: 71px;
width: 71px;
}
}

50
css/mobile.css Normal file
View File

@ -0,0 +1,50 @@
@media (max-width: 1024px) {
.logo {
background-size: 90px 44px !important;
height: 41px;
}
.header-content {
font-size: 70%;
line-height: 120%;
font-weight: normal;
}
.line-dashed-v {
border: none !important;
}
.top-bar-section ul li>a {
font-size: 70%;
}
}
@media (max-width: 640px) {
.hide_menu {
display: none;
}
.show_menu {
display: block;
}
.top-bar-section ul li {
width: 100%;
}
.top-bar-section ul li>a {
padding: 0 0 0 15px;
}
.top-bar {
background: #1ABC9C;
}
.header-content .small-7 {
text-align: right !important;
padding-top: 0;
}
.box-copayers figure {
height: 71px;
width: 71px;
}
}

View File

@ -175,10 +175,6 @@ small.has-error {
border-radius: 10px;
}
.transactions button, .transactions .button {
padding: 0.5rem 2rem;
}
button.radius, .button.radius {
-webkit-border-radius: 5px;
border-radius: 5px;
@ -325,3 +321,28 @@ input.ng-invalid-wallet-secret {
background: #fff;
}
.tooltip {
background: #16A085;
color: #fff;
font-weight: normal;
font-size: 12px;
padding: 3px 5px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
border: 1px solid #16A085;
}
.tooltip>.nub {
border-color:transparent transparent #16A085 transparent;
}
.tooltip.tip-top>.nub {
border-color:#16A085 transparent transparent transparent;
}
.tooltip.tip-right>.nub {
border-color:transparent #16A085 transparent transparent;
}
.tooltip.tip-left>.nub {
border-color:transparent transparent transparent #16A085;
}

View File

@ -9,6 +9,7 @@
<link rel="stylesheet" href="css/foundation-icons.css">
<link rel="stylesheet" href="lib/angular/angular-csp.css">
<link rel="stylesheet" href="css/main.css">
<link rel="stylesheet" href="css/mobile.css">
<link rel="shortcut icon" href="img/favicon.ico">
</head>
<body ng-cloak class="ng-cloak">
@ -16,10 +17,10 @@
<div data-ng-init="init()" data-ng-controller="HeaderController">
<div class="header">
<div class="header-content">
<div class="large-3 medium-3 small-3 columns">
<div class="large-3 medium-3 small-5 columns">
<span class="logo"></span>
</div>
<div class="large-9 medium-9 small-9 columns text-center p10t" ng-show="$root.wallet">
<div class="large-9 medium-9 small-7 columns text-center p10t" ng-show="$root.wallet && $root.wallet.publicKeyRing.isComplete()">
<div class="large-4 medium-4 columns line-dashed-v">
<a href="#/addresses" class="has-tip" tooltip-placement="bottom" tooltip="ID: {{$root.wallet.id}}">
<strong><span>{{$root.wallet.getName()}}</span></strong>
@ -31,26 +32,26 @@
ng-click="signout()"><i class="fi-power"></i></a>
</div>
<div class="large-4 medium-4 columns line-dashed-v">
Balance<br>
Balance<br class="hide-for-small">
<span ng-if="$root.updatingBalance">
<i class="fi-bitcoin-circle icon-rotate spinner"></i>
</span>
<span ng-if="!$root.updatingBalance" tooltip="{{totalBalanceBTC}} BTC" tooltip-trigger="mouseenter" tooltip-placement="bottom">{{totalBalance || 0 |number}} {{$root.unitName}}
<span ng-if="!$root.updatingBalance" data-options="disable_for_touch:true" tooltip="{{totalBalanceBTC}} BTC" tooltip-trigger="mouseenter" tooltip-placement="bottom">{{totalBalance || 0 |number}} {{$root.unitName}}
</span>
</div>
<div class="large-4 medium-4 columns">
Available to Spend<br>
Available to Spend<br class="hide-for-small">
<span ng-if="$root.updatingBalance">
<i class="fi-bitcoin-circle icon-rotate spinner"></i>
</span>
<span ng-show="!$root.updatingBalance" tooltip="{{availableBalanceBTC}} BTC" tooltip-trigger="mouseenter" tooltip-placement="bottom">{{availableBalance || 0|number}} {{$root.unitName}}
<span ng-show="!$root.updatingBalance" data-options="disable_for_touch:true" tooltip="{{availableBalanceBTC}} BTC" tooltip-trigger="mouseenter" tooltip-placement="bottom">{{availableBalance || 0|number}} {{$root.unitName}}
</span>
</div>
</div>
</div>
<nav class="top-bar" data-topbar ng-show="$root.wallet">
<nav class="top-bar" data-topbar ng-show="$root.wallet && $root.wallet.publicKeyRing.isComplete()">
<ul class="title-area">
<li class="name"></li>
<li class="toggle-topbar menu-icon">
@ -99,9 +100,9 @@
</div>
</div>
<div class="row">
<div ng-if='$root.wallet && !$root.wallet.publicKeyRing.isComplete() && !loading'>
<div class="medium-12 small-12 columns">
<div class="row">
<div class="large-12 medium-12 small-12 columns">
<div class="alert-box secondary radius" data-alert>
<i class="fi-info"></i>
Not all copayers have joined your wallet yet.
@ -114,8 +115,10 @@
yet to join.
</div>
</div>
</div>
<div class="medium-12 small-12 columns ">
<div class="row">
<div class="large-12 medium-12 small-12 columns ">
<div class="panel radius m30v">
<h3 class="m15b">Share this secret with your other copayers
<small> for them to join your wallet</small>
@ -134,18 +137,27 @@
</div>
</div>
</div>
<div class="row">
<div class="large-12 medium-12 small-12 columns ">
<div class="box-setup-copayers">
<div class="box-setup-copayers-fix">
<img class="box-setup-copay" ng-repeat="i in getNumber($root.wallet.totalCopayers) track by $index" src="./img/satoshi.gif" alt="Copayer {{$index+1}}-{{totalCopayers}}" ng-class="{'box-setup-copay-required': ($index+1) <= $root.wallet.publicKeyRing.registeredCopayers()}">
</div>
</div>
</div>
</div>
</div>
</div>
<div notifications="middle right"></div>
<div id="main" class="row" ng-class="{'main-home': !$root.wallet}">
<div id="main" class="row" ng-class="{'main-home': !$root.wallet || !$root.wallet.publicKeyRing.isComplete()}">
<div class="large-12 columns" ng-view></div>
</div>
</div>
<div id="footer" data-ng-controller="FooterController" ng-class="{'footer-home': !$root.wallet}">
<div id="footer" data-ng-controller="FooterController" ng-class="{'footer-home': !$root.wallet || !$root.wallet.publicKeyRing.isComplete()}">
<link rel="stylesheet" ng-href="{{theme}}">
<div ng-show="!$root.wallet">
<div class="large-12 columns text-left">
@ -153,8 +165,20 @@
<small>v{{version}}</small>
</div>
</div>
<div class="p10t" ng-show="$root.wallet">
<div class="large-3 medium-3 hide-for-small columns">
<div ng-show="$root.wallet && !$root.wallet.publicKeyRing.isComplete()">
<div class="large-6 medium-6 small-6 columns">
<strong>{{$root.wallet.getName()}}</strong>
{{$root.wallet.requiredCopayers}}-of-{{$root.wallet.totalCopayers}}
<small ng-if="$root.wallet.getNetworkName()=='livenet'">[LIVENET]</small>
<small ng-if="$root.wallet.getNetworkName()=='testnet'">[TESTNET]</small>
</div>
<div class="large-6 medium-6 small-6 columns text-right">
Copay
<small>v{{version}}</small>
</div>
</div>
<div ng-show="$root.wallet && $root.wallet.publicKeyRing.isComplete()">
<div class="large-3 medium-4 hide-for-small columns">
<div>
<strong>{{$root.wallet.getName()}}</strong>
</div>
@ -171,8 +195,7 @@
<a class="size-12" ng-click="change_theme(th)" ng-repeat="th in themes">{{th}} {{$last ? '' : '&middot; '}}</a>
</div>
</div>
<div class="large-9 medium-9 small-9 columns">
<a href="#/addresses" > </a>
<div class="large-9 medium-8 small-12 columns">
<!-- <div class="bottom&#45;copay" ng&#45;repeat="c in $root.wallet.getRegisteredPeerIds()" class="has&#45;tip" tooltip&#45;popup&#45;delay="1000" tooltip&#45;placement="top" tooltip="{{c.nick}}"> -->
<div class="bottom-copay" ng-repeat="c in $root.wallet.getRegisteredPeerIds()">
<video ng-if="$root.videoInfo[c.peerId]"
@ -312,7 +335,7 @@
</label>
</div>
<div class="small-12 medium-6 large-6 columns">
<label>Your Wallet Password <small class="has-tip" tooltip="doesn't need to be shared">Required</small>
<label>Your Wallet Password <small data-options="disable_for_touch:true" class="has-tip" tooltip="doesn't need to be shared">Required</small>
<input type="password" placeholder="Choose your password" class="form-control"
ng-model="$parent.walletPassword" check-strength="passwordStrength" tooltip-html-unsafe="Password strength: {{passwordStrength}}<br/><small>Tip: Use lower and uppercase, numbers and symbols</small>" tooltip-trigger="focus" required>
</label>
@ -390,7 +413,7 @@
</span>
</a>
<a class="secondary radius" ng-click="showAll=!showAll" ng-show="(addresses|withoutFunds) > 1">
<a class="secondary radius" ng-click="showAll=!showAll" ng-show="addresses.length != (addresses|limitAddress).length">
<span ng-if="!showAll">Show all</span>
<span ng-if="showAll">Show less</span>
</a>
@ -652,6 +675,7 @@
<div class="row collapse">
<label for="amount">Amount
<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="has-error" ng-show="sendForm.amount.$invalid && !sendForm.amount.$pristine && !notEnoughAmount">
Not valid
@ -687,14 +711,14 @@
</div>
<div class="row">
<div class="large-12 medium-6 columns">
<div class="large-12 columns">
<div class="row collapse">
<label for="comment">Note
<small ng-hide="!sendForm.comment.$pristine">optional</small>
<small class="is-valid" ng-show="!sendForm.comment.$invalid && !sendForm.comment.$pristine">valid!</small>
<small class="has-error" ng-show="sendForm.comment.$invalid && !sendForm.comment.$pristine">too long!</small>
</label>
<div class="small-12 columns">
<div class="large-12 columns">
<textarea id="comment" ng-disabled="loading"
name="comment" placeholder="Leave a private message to your copayers" ng-model="commentText" ng-maxlength="100"></textarea>
</div>
@ -714,7 +738,7 @@
<div class="medium-8 medium-centered large-8 large-centered columns">
<hr>
<h3>Address Book</h3>
<p class="text-gray" ng-hide="showAddressBook()">Empry. Create some alias for addresses</p>
<p class="text-gray" ng-hide="showAddressBook()">Empty. Create an alias for your addresses</p>
<table ng-show="showAddressBook()">
<thead>
<tr>
@ -767,16 +791,16 @@
<script type="text/ng-template" id="backup.html">
<div class="backup" ng-controller="BackupController">
<h3>{{title}}</h3>
<div class="row text-center">
<div class="large-6 medium-6 columns">
<a class="panel radius box-backup" ng-click="download()">
<div class="row">
<div class="large-4 medium-6 columns large-centered medium-centered">
<a class="panel radius box-backup text-center" ng-click="download()">
<i class="fi-download size-72"></i>
<p> Download File </p>
</a>
</div>
<div class="row text-center small" style="margin-top:70px">
<div class="button radius warning" ng-really-message="Are you sure to delete this wallet from this computer?" ng-really-click="deleteWallet()">Delete this wallet from this computer</div>
</div>
<div class="row text-center">
<div class="button radius warning small m30v" ng-really-message="Are you sure to delete this wallet from this computer?" ng-really-click="deleteWallet()">Delete this wallet from this computer</div>
</div>
</div>
</script>

View File

@ -34,4 +34,3 @@ angular.module('copayApp.filters', []);
angular.module('copayApp.services', []);
angular.module('copayApp.controllers', []);
angular.module('copayApp.directives', []);

View File

@ -4,8 +4,7 @@ angular.module('copayApp.controllers').controller('FooterController', function($
if (config.themes && Array.isArray(config.themes) && config.themes[0]) {
$scope.themes = config.themes;
}
else {
} else {
$scope.themes = ['default'];
}

View File

@ -2,8 +2,7 @@
angular.module('copayApp.controllers').controller('HeaderController',
function($scope, $rootScope, $location, notification, $http, controllerUtils) {
$scope.menu = [
{
$scope.menu = [{
'title': 'Addresses',
'icon': 'fi-address-book',
'link': '#/addresses'
@ -21,14 +20,26 @@ angular.module('copayApp.controllers').controller('HeaderController',
'link': '#/backup'
}];
$scope.getNumber = function(num) {
return new Array(num);
}
$http.get('https://api.github.com/repos/bitpay/copay/tags').success(function(data) {
var toInt = function (s) { return parseInt(s); };
var toInt = function(s) {
return parseInt(s);
};
var latestVersion = data[0].name.replace('v', '').split('.').map(toInt);
var currentVersion = copay.version.split('.').map(toInt);
if (currentVersion[0] < latestVersion[0]) {
$scope.updateVersion = {class: 'error', version:data[0].name};
$scope.updateVersion = {
class: 'error',
version: data[0].name
};
} else if (currentVersion[0] == latestVersion[0] && currentVersion[1] < latestVersion[1]) {
$scope.updateVersion = {class: 'info', version:data[0].name};
$scope.updateVersion = {
class: 'info',
version: data[0].name
};
}
});

View File

@ -9,7 +9,10 @@ angular.module('copayApp.controllers').controller('ImportController',
walletFactory.import(encryptedObj, passphrase, function(err, w) {
if (err) {
$scope.loading = false;
$rootScope.$flashMessage = { message: err.errMsg || 'Wrong password', type: 'error'};
$rootScope.$flashMessage = {
message: err.errMsg || 'Wrong password',
type: 'error'
};
$rootScope.$digest();
return;
}
@ -43,7 +46,10 @@ angular.module('copayApp.controllers').controller('ImportController',
$scope.import = function(form) {
if (form.$invalid) {
$scope.loading = false;
$rootScope.$flashMessage = { message: 'There is an error in the form. Please, try again', type: 'error'};
$rootScope.$flashMessage = {
message: 'There is an error in the form. Please, try again',
type: 'error'
};
return;
}
@ -53,7 +59,10 @@ angular.module('copayApp.controllers').controller('ImportController',
if (!backupFile && !backupText) {
$scope.loading = false;
$rootScope.$flashMessage = { message: 'Please, select your backup file or paste the text', type: 'error'};
$rootScope.$flashMessage = {
message: 'Please, select your backup file or paste the text',
type: 'error'
};
$scope.loading = false;
return;
}
@ -62,8 +71,7 @@ angular.module('copayApp.controllers').controller('ImportController',
if (backupFile) {
reader.readAsBinaryString(backupFile);
}
else {
} else {
_importBackup(backupText);
}
};

View File

@ -33,7 +33,7 @@ angular.module('copayApp.controllers').controller('SendController',
$scope.submitForm = function(form) {
if (form.$invalid) {
$rootScope.$flashMessage = {
message: 'You can not send a proposal transaction. Please, try again',
message: 'Unable to send a transaction proposal. Please, try again',
type: 'error'
};
return;
@ -254,4 +254,8 @@ angular.module('copayApp.controllers').controller('SendController',
});
};
$scope.topAmount = function() {
var maxSat = ($rootScope.availableBalance * config.unitToSatoshi).toFixed(0) - bitcore.TransactionBuilder.FEE_PER_1000B_SAT;
$scope.amount = maxSat / config.unitToSatoshi;
};
});

View File

@ -1,11 +1,13 @@
'use strict';
angular.module('copayApp.filters', [])
.filter('amTimeAgo', ['amMoment', function(amMoment) {
.filter('amTimeAgo', ['amMoment',
function(amMoment) {
return function(input) {
return amMoment.preprocessDate(input).fromNow();
};
}])
}
])
.filter('paged', function() {
return function(elements) {
if (elements) {
@ -17,41 +19,15 @@ angular.module('copayApp.filters', [])
})
.filter('limitAddress', function() {
return function(elements, showAll) {
var addrs = [];
if (elements.length > 0) {
if (showAll) {
if (elements.length <= 1 || showAll) {
return elements;
}
if (elements.length == 1) {
return elements;
}
else {
for (var i=0;i<elements.length;i++) {
if (!elements[i].isChange && (!elements[i].balance || elements[i].balance == 0)) {
addrs.push(elements[i]);
break;
}
}
for (var i=0;i<elements.length;i++) {
if (elements[i].balance && elements[i].balance > 0) {
addrs.push(elements[i]);
}
}
// Show last 3 non-change addresses plus those with balance
var addrs = elements.filter(function(e, i) {
return (!e.isChange && i < 3) || (e.balance && e.balance > 0);
});
return addrs;
}
}
};
})
.filter('withoutFunds', function() {
return function(elements) {
var len = 0;
for (var i=0;i<elements.length;i++) {
if (!elements[i].balance || elements[i].balance == 0) {
len++;
}
}
return len;
};
})
;
});

View File

@ -168,14 +168,28 @@ Insight.prototype.checkActivity = function(addresses, cb) {
if (!addresses) throw new Error('address must be set');
this.getTransactions(addresses, function onResult(txs) {
var flatArray = function (xss) { return xss.reduce(function(r, xs) { return r.concat(xs); }, []); };
var getInputs = function (t) { return t.vin.map(function (vin) { return vin.addr }); };
var getOutputs = function (t) { return flatArray(
t.vout.map(function (vout) { return vout.scriptPubKey.addresses; })
);};
var flatArray = function(xss) {
return xss.reduce(function(r, xs) {
return r.concat(xs);
}, []);
};
var getInputs = function(t) {
return t.vin.map(function(vin) {
return vin.addr
});
};
var getOutputs = function(t) {
return flatArray(
t.vout.map(function(vout) {
return vout.scriptPubKey.addresses;
})
);
};
var activityMap = new Array(addresses.length);
var activeAddress = flatArray(txs.map(function(t) { return getInputs(t).concat(getOutputs(t)); }));
var activeAddress = flatArray(txs.map(function(t) {
return getInputs(t).concat(getOutputs(t));
}));
activeAddress.forEach(function(addr) {
var index = addresses.indexOf(addr);
if (index != -1) activityMap[index] = true;

View File

@ -84,8 +84,12 @@ PrivateKey.prototype.getForPath = function(path) {
var derivedHK = this._getHK(path);
pk = this.privateKeyCache[path] = derivedHK.eckey.private.toString('hex');
}
var wk = new WalletKey({network: this.network});
wk.fromObj({priv: pk});
var wk = new WalletKey({
network: this.network
});
wk.fromObj({
priv: pk
});
return wk;
};

View File

@ -146,8 +146,7 @@ Wallet.prototype._handleAddressBook = function(senderId, data, isInbound) {
if (!this.addressBook[key]) {
this.addressBook[key] = rcv[key];
hasChange = true;
}
else {
} else {
if (rcv[key].createdTs > this.addressBook[key].createdTs) {
this.addressBook[key] = rcv[key];
hasChange = true;
@ -804,7 +803,9 @@ Wallet.prototype.indexDiscovery = function(start, change, gap, cb) {
next();
});
},
function _while() { return hasActivity; },
function _while() {
return hasActivity;
},
function _finnaly(err) {
if (err) return cb(err);
cb(null, lastActive);

View File

@ -272,9 +272,7 @@ Network.prototype._addCopayerMap = function(peerId, copayerId) {
if (!this.copayerForPeer[peerId]) {
if (Object.keys(this.copayerForPeer).length < this.maxPeers) {
this.copayerForPeer[peerId] = copayerId;
}
else {
}
} else {}
}
};
@ -426,7 +424,9 @@ Network.prototype.lockIncommingConnections = function(allowedCopayerIdsArray) {
Network.prototype.disconnect = function(cb, forced) {
var self = this;
self.closing = 1;
self.send(null, { type: 'disconnect' }, function(){
self.send(null, {
type: 'disconnect'
}, function() {
self.cleanUp();
if (typeof cb === 'function') cb();
});

View File

@ -2,8 +2,7 @@
var imports = require('soop').imports();
function Storage() {
}
function Storage() {}
Storage.prototype._read = function(k) {
var ret;

View File

@ -67,8 +67,7 @@ angular
if (!util.supports.data) {
$location.path('unsupported');
}
else {
} else {
if ((!$rootScope.wallet || !$rootScope.wallet.id) && next.validate) {
$location.path('signin');
}

View File

@ -1,19 +1,41 @@
'use strict';
angular.module('copayApp.services').
factory('notification', ['$timeout',function($timeout){
factory('notification', ['$timeout',
function($timeout) {
var notifications = JSON.parse(localStorage.getItem('notifications')) || [],
queue = [];
var settings = {
info: { duration: 5000, enabled: true },
funds: { duration: 5000, enabled: true },
warning: { duration: 5000, enabled: true },
error: { duration: 1e10, enabled: true },
success: { duration: 5000, enabled: true },
progress: { duration: 0, enabled: true },
custom: { duration: 35000, enabled: true },
info: {
duration: 5000,
enabled: true
},
funds: {
duration: 5000,
enabled: true
},
warning: {
duration: 5000,
enabled: true
},
error: {
duration: 1e10,
enabled: true
},
success: {
duration: 5000,
enabled: true
},
progress: {
duration: 0,
enabled: true
},
custom: {
duration: 35000,
enabled: true
},
details: true,
localStorage: false,
html5Mode: false,
@ -33,8 +55,7 @@ angular.module('copayApp.services').
noti.onclose = onclose;
}
noti.show();
}
else {
} else {
settings.html5Mode = false;
}
}
@ -77,20 +98,17 @@ angular.module('copayApp.services').
if (window.webkitNotifications) {
if (window.webkitNotifications.checkPermission() === 0) {
return true;
}
else{
} else {
window.webkitNotifications.requestPermission(function() {
if (window.webkitNotifications.checkPermission() === 0) {
settings.html5Mode = true;
}
else{
} else {
settings.html5Mode = false;
}
});
return false;
}
}
else{
} else {
return false;
}
},
@ -167,8 +185,7 @@ angular.module('copayApp.services').
}, function() {
// inner on close function
});
}
else{
} else {
queue.push(notification);
$timeout(function removeFromQueueTimeout() {
queue.splice(queue.indexOf(notification), 1);
@ -200,7 +217,8 @@ angular.module('copayApp.services').
}
};
}]).
}
]).
directive('notifications', function(notification, $compile) {
/**
*
@ -244,7 +262,8 @@ angular.module('copayApp.services').
scope: {},
template: html,
link: link,
controller: ['$scope', function NotificationsCtrl( $scope ){
controller: ['$scope',
function NotificationsCtrl($scope) {
$scope.queue = notification.getQueue();
$scope.removeNotification = function(noti) {
@ -255,8 +274,3 @@ angular.module('copayApp.services').
};
});

View File

@ -1,4 +1,3 @@
'use strict';
angular.module('copayApp.services').value('walletFactory', new copay.WalletFactory(config, copay.version));

View File

@ -11,13 +11,14 @@
** there to be no references in the window to these libs, so let's trick
** the renderer into thinking that we are _not_ in a CommonJS environment.
*/
if (typeof module !== 'undefined') module = { exports: null };
if (typeof module !== 'undefined') module = {
exports: null
};
// are we running in copay shell?
if (window.process && process.type === 'renderer') {
window.cshell = initCopayShellBindings();
}
else {
} else {
return;
}
@ -40,7 +41,9 @@
// atom shell forces to implement the clipboard on our own - thanks obama.
Mousetrap.stopCallback = function() { return false };
Mousetrap.stopCallback = function() {
return false
};
Mousetrap.bind('ctrl+c', function(e) {
clipb.writeText(window.getSelection().toString());

View File

@ -6,7 +6,10 @@
var sys = require('sys')
var exec = require('child_process').exec;
function puts(error, stdout, stderr) { sys.puts(stdout) }
function puts(error, stdout, stderr) {
sys.puts(stdout)
}
function isNumber(n) {
return !isNaN(parseInt(n)) && isFinite(n);

View File

@ -1,3 +1,5 @@
if (typeof window != 'undefined') {
window.mocha.setup({ timeout: 5000 });
window.mocha.setup({
timeout: 5000
});
}

View File

@ -1,9 +1,7 @@
var imports = require('soop').imports();
var EventEmitter = imports.EventEmitter || require('events').EventEmitter;
function Network(opts) {
}
function Network(opts) {}
Network.parent = EventEmitter;
@ -34,10 +32,8 @@ Network.prototype.lockIncommingConnections = function() {
};
Network.prototype.getPeer = function() {
};
Network.prototype.connectToCopayers = function(cps) {
};
Network.prototype.getPeer = function() {};
Network.prototype.connectToCopayers = function(cps) {};
Network.prototype.isOnline = function() {
return true;
};

View File

@ -18,7 +18,9 @@ describe('API', function() {
it('should have a command called "echo"', function() {
var api = new API({Storage: Storage});
var api = new API({
Storage: Storage
});
should.exist(api.echo);
});
@ -32,7 +34,9 @@ describe('API', function() {
})
it('should throw an error for all commands when called with wrong number of arguments', function() {
var api = new API({Storage: Storage});
var api = new API({
Storage: Storage
});
for (var i in API.prototype) {
var f = API.prototype[i];
if (i[0] != '_' && typeof f == 'function') {
@ -59,7 +63,9 @@ describe('API', function() {
describe('#echo', function() {
it('should echo a string', function(done) {
var api = new API({Storage: Storage});
var api = new API({
Storage: Storage
});
var str = 'mystr';
api.echo(str, function(err, result) {
result.should.equal(str);
@ -70,7 +76,9 @@ describe('API', function() {
describe('#echoNumber', function() {
it('should echo a number', function(done) {
var api = new API({Storage: Storage});
var api = new API({
Storage: Storage
});
var num = 500;
api.echoNumber(num, function(err, result) {
result.should.equal(num);
@ -82,8 +90,12 @@ describe('API', function() {
describe('#echoObject', function() {
it('should echo an object', function(done) {
var api = new API({Storage: Storage});
var obj = {test:'test'};
var api = new API({
Storage: Storage
});
var obj = {
test: 'test'
};
api.echoObject(obj, function(err, result) {
result.test.should.equal(obj.test);
(typeof result).should.equal('object');
@ -94,7 +106,9 @@ describe('API', function() {
describe('#getArgTypes', function() {
it('should get the argTypes of echo', function(done) {
var api = new API({Storage: Storage});
var api = new API({
Storage: Storage
});
api.getArgTypes('echo', function(err, result) {
result[0][1].should.equal('string');
done();
@ -104,7 +118,9 @@ describe('API', function() {
describe('#getCommands', function() {
it('should get all the commands', function(done) {
var api = new API({Storage: Storage});
var api = new API({
Storage: Storage
});
var n = 0;
for (var i in api)
@ -120,7 +136,9 @@ describe('API', function() {
describe('#getWallets', function() {
it('should get the wallet ids', function(done) {
var api = new API({Storage: Storage});
var api = new API({
Storage: Storage
});
api.getWallets(function(err, result) {
result.length.should.be.greaterThan(-1);
done();
@ -130,7 +148,9 @@ describe('API', function() {
describe('#help', function() {
it('should call _cmd_getCommands', function(done) {
var api = new API({Storage: Storage});
var api = new API({
Storage: Storage
});
api._cmd_getCommands = function(callback) {
(typeof arguments[0]).should.equal('function');
callback(null, ['item']);

View File

@ -84,5 +84,3 @@ describe('AddressIndex model', function() {
});
});

View File

@ -21,5 +21,3 @@ describe('Passphrase model', function() {
});
});

View File

@ -31,7 +31,10 @@ var createW = function (networkName) {
}
w.walletId = '1234567';
return {w:w, copayers: copayers};
return {
w: w,
copayers: copayers
};
};
describe('PublicKeyRing model', function() {
@ -63,7 +66,9 @@ describe('PublicKeyRing model', function() {
w2.registeredCopayers().should.equal(0);
w2.isComplete().should.equal(false);
(function() {w2.getAddress(0, false);}).should.throw();
(function() {
w2.getAddress(0, false);
}).should.throw();
});
it('should add and check when adding shared pub keys', function() {
@ -74,7 +79,9 @@ describe('PublicKeyRing model', function() {
w.isComplete().should.equal(true);
w.addCopayer.should.throw();
for (var i = 0; i < 5; i++) {
(function() {w.addCopayer(copayers[i])}).should.throw();
(function() {
w.addCopayer(copayers[i])
}).should.throw();
}
});
@ -100,7 +107,9 @@ describe('PublicKeyRing model', function() {
w2.isComplete().should.equal(true);
w2.addCopayer.should.throw();
for (var i = 0; i < 5; i++) {
(function() {w.addCopayer(copayers[i])}).should.throw();
(function() {
w.addCopayer(copayers[i])
}).should.throw();
}
w2.indexes.getChangeIndex().should.equal(changeN);
@ -194,29 +203,39 @@ describe('PublicKeyRing model', function() {
networkName: 'testnet', //wrong
walletId: w.walletId,
});
(function() { w2.merge(w);}).should.throw();
(function() {
w2.merge(w);
}).should.throw();
var w3 = new PublicKeyRing({
networkName: 'livenet',
walletId: w.walletId,
requiredCopayers: 2, // wrong
});
(function() { w3.merge(w);}).should.throw();
(function() {
w3.merge(w);
}).should.throw();
var w4 = new PublicKeyRing({
networkName: 'livenet',
walletId: w.walletId,
totalCopayers: 3, // wrong
});
(function() { w4.merge(w);}).should.throw();
(function() {
w4.merge(w);
}).should.throw();
var w6 = new PublicKeyRing({
networkName: 'livenet',
});
(function() { w6.merge(w);}).should.throw();
(function() {
w6.merge(w);
}).should.throw();
w.networkName = 'livenet';
(function() { w6.merge(w);}).should.throw();
(function() {
w6.merge(w);
}).should.throw();
var w0 = new PublicKeyRing({
@ -227,7 +246,9 @@ describe('PublicKeyRing model', function() {
w0.addCopayer();
w0.addCopayer();
w0.addCopayer();
(function() { w0.merge(w);}).should.throw();
(function() {
w0.merge(w);
}).should.throw();
w.merge(w0, true).should.equal(true);
w.isComplete().should.equal(true);
@ -235,7 +256,9 @@ describe('PublicKeyRing model', function() {
networkName: 'livenet',
});
wx.addCopayer();
(function() { w.merge(wx);}).should.throw();
(function() {
w.merge(wx);
}).should.throw();
});
@ -370,5 +393,3 @@ describe('PublicKeyRing model', function() {
});
});

View File

@ -135,24 +135,45 @@ describe('Insight model', function() {
w.checkActivity(addresses, function(err, actives) {
console.log(err);
actives.length.should.equal(addresses.length);
actives.filter(function(i) { return i }).length.should.equal(0);
actives.filter(function(i) {
return i
}).length.should.equal(0);
done();
});
});
it('#checkActivity for active addreses', function(done) {
var w = new Insight();
w.getTransactions = function(addresses, cb) {
cb([
{vin: [{ addr: '2NATQJnaQe2CUKLyhL1zdNkttJM1dUH9HaM'}], vout: []},
{vin: [{ addr: '2NATQJnaQe2CUKLyhL1zdNkttJM1dUH9HaM'}], vout: []},
{vin: [{ addr: '2N9D5bcCQ2bPWUDByQ6Qb5bMgMtgsk1rw3x'}], vout: []},
{vin: [], vout: [{scriptPubKey: {addresses: ['2NFjCBFZSsxiwWAD7CKQ3hzWFtf9DcqTucY']}}]}
]);
cb([{
vin: [{
addr: '2NATQJnaQe2CUKLyhL1zdNkttJM1dUH9HaM'
}],
vout: []
}, {
vin: [{
addr: '2NATQJnaQe2CUKLyhL1zdNkttJM1dUH9HaM'
}],
vout: []
}, {
vin: [{
addr: '2N9D5bcCQ2bPWUDByQ6Qb5bMgMtgsk1rw3x'
}],
vout: []
}, {
vin: [],
vout: [{
scriptPubKey: {
addresses: ['2NFjCBFZSsxiwWAD7CKQ3hzWFtf9DcqTucY']
}
}]
}]);
};
w.checkActivity(addresses, function(err, actives) {
actives.length.should.equal(addresses.length);
actives.filter(function(i) { return i }).length.should.equal(3);
actives.filter(function(i) {
return i
}).length.should.equal(3);
done();
});
});

View File

@ -95,7 +95,9 @@ describe('Network / WebRTC', function() {
key.regenerateSync();
var copayerId = key.public.toString('hex');
n._sendToOne = function(a1, a2, a3, cb) {cb();};
n._sendToOne = function(a1, a2, a3, cb) {
cb();
};
var sig = undefined;
n.send(copayerId, data, function() {
done();
@ -138,7 +140,9 @@ describe('Network / WebRTC', function() {
key.regenerateSync();
var copayerIds = [key.public.toString('hex')];
n._sendToOne = function(a1, a2, a3, cb) {cb();};
n._sendToOne = function(a1, a2, a3, cb) {
cb();
};
var sig = undefined;
n.send(copayerIds, data, function() {
done();

View File

@ -17,12 +17,18 @@ describe('Storage/File', function() {
var fs = {}
fs.readFile = function(filename, callback) {
filename.should.equal('myfilename');
var obj = {"test":"test"};
var obj = {
"test": "test"
};
var encryptedStr = CryptoJS.AES.encrypt(JSON.stringify(obj), "password").toString();
callback(null, encryptedStr);
};
var Storage = require('soop').load('../js/models/storage/File.js', {fs: fs});
var storage = new Storage({password: 'password'});
var Storage = require('soop').load('../js/models/storage/File.js', {
fs: fs
});
var storage = new Storage({
password: 'password'
});
storage.load('myfilename', function(err) {
done();
});
@ -36,8 +42,12 @@ describe('Storage/File', function() {
filename.should.equal('myfilename');
callback();
};
var Storage = require('soop').load('../js/models/storage/File.js', {fs: fs});
var storage = new Storage({password: 'password'});
var Storage = require('soop').load('../js/models/storage/File.js', {
fs: fs
});
var storage = new Storage({
password: 'password'
});
storage.save('myfilename', function(err) {
done();
});
@ -47,7 +57,11 @@ describe('Storage/File', function() {
describe('#_read', function() {
it('should return the value of a key', function() {
var storage = new Storage();
storage.data = {'walletId':{'test':'data'}};
storage.data = {
'walletId': {
'test': 'data'
}
};
storage._read('walletId::test').should.equal('data');
});
});
@ -68,7 +82,11 @@ describe('Storage/File', function() {
describe('#getGlobal', function() {
it('should call storage._read', function() {
var storage = new Storage();
storage.data = {'walletId':{'test':'test'}};
storage.data = {
'walletId': {
'test': 'test'
}
};
storage._read = sinon.spy();
storage.getGlobal('walletId::test');
storage._read.calledOnce.should.equal(true);
@ -91,7 +109,11 @@ describe('Storage/File', function() {
describe('#removeGlobal', function() {
it('should remove a global key', function(done) {
var storage = new Storage();
storage.data = {'walletId':{'key':'value'}};
storage.data = {
'walletId': {
'key': 'value'
}
};
storage.save = function(walletId, callback) {
should.not.exist(storage.data[walletId]['key']);
callback();
@ -141,7 +163,9 @@ describe('Storage/File', function() {
describe('#setFromObj', function() {
it('should set this object for a wallet', function(done) {
var obj = {test:'testval'};
var obj = {
test: 'testval'
};
var storage = new Storage();
storage.save = function(walletId, callback) {
callback();
@ -155,12 +179,16 @@ describe('Storage/File', function() {
describe('#getEncryptedObj', function() {
it('should give an encrypted object', function() {
var obj = {test:'testval'};
var obj = {
test: 'testval'
};
var data = JSON.stringify(obj);
var encrypted = CryptoJS.AES.encrypt(data, 'password');
var base64 = encrypted.toString();
var storage = new Storage({password: 'password'});
var storage = new Storage({
password: 'password'
});
storage.data['walletId'] = obj;
var enc = storage.getEncryptedObj('walletId');

View File

@ -38,11 +38,17 @@ if (typeof process === 'undefined' || !process.version) {
1, 1000, -15, -1000,
0.1, -0.5, -0.5e-10, Math.PI,
'hi', 'auydoaiusyodaisudyoa', '0b5b8556a0c2ce828c9ccfa58b3dd0a1ae879b9b',
'1CjPR7Z5ZSyWk6WtXvSFgkptmpoi4UM9BC', 'OP_DUP OP_HASH160 80ad90d4035',
[1,2,3,4,5,6],
{ x: 1, y: 2},
{ x: 'hi', y: null},
{ a: {}, b: [], c: [1,2,'hi']},
'1CjPR7Z5ZSyWk6WtXvSFgkptmpoi4UM9BC', 'OP_DUP OP_HASH160 80ad90d4035', [1, 2, 3, 4, 5, 6], {
x: 1,
y: 2
}, {
x: 'hi',
y: null
}, {
a: {},
b: [],
c: [1, 2, 'hi']
},
null
];
getSetData.forEach(function(obj) {
@ -56,9 +62,13 @@ if (typeof process === 'undefined' || !process.version) {
describe('#export', function() {
it('should export the encrypted wallet', function() {
var storage = new LocalEncrypted({password: 'password'});
var storage = new LocalEncrypted({
password: 'password'
});
storage.set(fakeWallet, timeStamp, 'testval');
var obj = {test:'testval'};
var obj = {
test: 'testval'
};
var encrypted = storage.export(obj);
encrypted.length.should.be.greaterThan(10);
localStorage.removeItem(fakeWallet + '::' + timeStamp);

View File

@ -55,6 +55,25 @@ describe("Unit: Controllers", function() {
});
});
describe('Setup Controller', function() {
var setupCtrl;
beforeEach(inject(function($controller, $rootScope) {
scope = $rootScope.$new();
setupCtrl = $controller('SetupController', {
$scope: scope,
});
}));
describe('#getNumber', function() {
it('should return an array of n undefined elements', function() {
var n = 5;
var array = scope.getNumber(n);
expect(array.length).equal(n);
});
});
});
describe('Address Controller', function() {
var addressCtrl;
beforeEach(inject(function($controller, $rootScope) {
@ -109,10 +128,13 @@ describe("Unit: Controllers", function() {
);
scope.model = {
newaddress: null,
newlabel: null
newlabel: null,
};
$compile(element)(scope);
$controller('SendController', {$scope: scope});
$controller('SendController', {
$scope: scope,
$modal: {},
});
scope.$digest();
form = scope.form;
}));
@ -212,12 +234,20 @@ describe("Unit: Controllers", function() {
scope.$apply();
});
it('should return an array of n undefined elements', function() {
$httpBackend.flush(); // need flush
var n = 5;
var array = scope.getNumber(n);
expect(array.length).equal(n);
});
});
describe('Send Controller', function() {
var sendCtrl;
beforeEach(inject(function($controller, $rootScope) {
scope = $rootScope.$new();
$rootScope.availableBalance = 123456;
sendCtrl = $controller('SendController', {
$scope: scope,
$modal: {},
@ -227,6 +257,10 @@ describe("Unit: Controllers", function() {
it('should have a SendController', function() {
expect(scope.isMobile).not.to.equal(null);
});
it('should autotop balance correctly', function() {
scope.topAmount();
expect(scope.amount).to.equal(123356);
});
});
});

View File

@ -85,7 +85,11 @@ describe("Unit: Testing Directives", function() {
beforeEach(inject(function($compile, $rootScope) {
$rootScope.wallet = {
addressBook: {'2MtBXKLtZuXGDshUcyH6yq7aZ33Snbb49pT': {label: ':)'}}
addressBook: {
'2MtBXKLtZuXGDshUcyH6yq7aZ33Snbb49pT': {
label: ':)'
}
}
}
element1 = angular.element(
'<contact address="2MtBXKLtZuXGDshUcyH6yq7aZ33Snbb49pT" />'

View File

@ -1,6 +1,71 @@
'use strict';
//
// test/unit/filters/filtersSpec.js
//
describe("Unit: Testing Filters", function() {
describe('Unit: Testing Filters', function() {
beforeEach(module('copayApp.filters'));
describe('limitAddress', function() {
it('should handle emtpy list', inject(function($filter) {
var limitAddress = $filter('limitAddress');
expect(limitAddress([], false)).to.be.empty;
}));
it('should honor show all', inject(function($filter) {
var limitAddress = $filter('limitAddress');
var addresses = [{}, {}, {}, {}, {}];
expect(limitAddress(addresses, true).length).to.equal(5);
expect(limitAddress([{}], false).length).to.equal(1);
}));
it('should filter correctly', inject(function($filter) {
var limitAddress = $filter('limitAddress');
var addresses = [{
isChange: true,
balance: 0
}, {
isChange: false,
balance: 0
}, {
isChange: true,
balance: 0
}, {
isChange: false,
balance: 0
}, {
isChange: true,
balance: 0
}, {
isChange: false,
balance: 0
}, {
isChange: true,
balance: 0
}, {
isChange: false,
balance: 0
}];
expect(limitAddress(addresses, false).length).to.equal(1);
addresses[0].isChange = false;
expect(limitAddress(addresses, false).length).to.equal(2);
addresses[2].isChange = false;
expect(limitAddress(addresses, false).length).to.equal(3);
addresses[3].isChange = false;
expect(limitAddress(addresses, false).length).to.equal(3);
addresses[0].balance = 20;
expect(limitAddress(addresses, false).length).to.equal(3);
addresses[0].balance = 20;
expect(limitAddress(addresses, false).length).to.equal(3);
addresses[7].balance = 20;
expect(limitAddress(addresses, false).length).to.equal(4);
}));
});
});