diff --git a/app/controllers/currency.js b/app/controllers/currency.js new file mode 100644 index 0000000..e635a7b --- /dev/null +++ b/app/controllers/currency.js @@ -0,0 +1,71 @@ +'use strict'; + +var config = require('../../config/config'); + +// Set the initial vars +var timestamp = +new Date(), + delay = config.currencyRefresh * 60000, + bitstampRate = 0; + +exports.index = function(req, res) { + + var _xhr = function() { + if (typeof XMLHttpRequest !== 'undefined' && XMLHttpRequest !== null) { + return new XMLHttpRequest(); + } else if (typeof require !== 'undefined' && require !== null) { + var XMLhttprequest = require('xmlhttprequest').XMLHttpRequest; + return new XMLhttprequest(); + } + }; + + var _request = function(url, cb) { + var request; + request = _xhr(); + request.open('GET', url, true); + request.onreadystatechange = function() { + if (request.readyState === 4) { + if (request.status === 200) { + return cb(false, request.responseText); + } + + return cb(true, { + status: request.status, + message: 'Request error' + }); + } + }; + + return request.send(null); + }; + + // Init + var currentTime = +new Date(); + console.log('-----------------------------------'); + console.log(timestamp); + console.log(currentTime); + console.log(currentTime >= (timestamp + delay)); + console.log('-----------------------------------'); + if (bitstampRate === 0 || currentTime >= (timestamp + delay)) { + timestamp = currentTime; + + _request('https://www.bitstamp.net/api/ticker/', function(err, data) { + if (!err) bitstampRate = parseFloat(JSON.parse(data).last); + + res.jsonp({ + status: 200, + data: { + bitstamp: bitstampRate, + delay: delay + } + }); + }); + } else { + res.jsonp({ + status: 200, + data: { + bitstamp: bitstampRate, + delay: delay + } + }); + } +}; diff --git a/app/views/includes/foot.jade b/app/views/includes/foot.jade index 305c244..323f372 100755 --- a/app/views/includes/foot.jade +++ b/app/views/includes/foot.jade @@ -30,6 +30,7 @@ script(type='text/javascript', src='/js/services/address.js') script(type='text/javascript', src='/js/services/transactions.js') script(type='text/javascript', src='/js/services/blocks.js') script(type='text/javascript', src='/js/services/socket.js') +script(type='text/javascript', src='/js/services/currency.js') //Application Controllers script(type='text/javascript', src='/js/controllers/index.js') diff --git a/config/config.js b/config/config.js index 92fbeb6..ef514d9 100644 --- a/config/config.js +++ b/config/config.js @@ -39,4 +39,7 @@ module.exports = { network: process.env.INSIGHT_NETWORK || 'testnet', disableP2pSync: false, disableHistoricSync: false, + + // Time to refresh the currency rate. In minutes + currencyRefresh: 10 }; diff --git a/config/express.js b/config/express.js index 2697554..4b96d0f 100644 --- a/config/express.js +++ b/config/express.js @@ -21,6 +21,9 @@ module.exports = function(app, historicSync) { app.set('views', config.root + '/app/views'); app.set('view engine', 'jade'); + // Compress JSON outputs + app.set('json spaces', 0); + //Enable jsonp app.enable('jsonp callback'); diff --git a/config/routes.js b/config/routes.js index 72b2b01..317e19d 100644 --- a/config/routes.js +++ b/config/routes.js @@ -30,6 +30,10 @@ module.exports = function(app) { app.get('/api/sync', st.sync); + // Currency + var currency = require('../app/controllers/currency'); + app.get('/api/currency', currency.index); + //Home route var index = require('../app/controllers/index'); app.get('/api/version', index.version); diff --git a/package.json b/package.json index 4a6e18d..5d60909 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,8 @@ "sinon": "~1.7.3", "chai": "~1.8.1", "bitcore": "git://github.com/bitpay/bitcore.git", - "bufferput": "git://github.com/bitpay/node-bufferput.git" + "bufferput": "git://github.com/bitpay/node-bufferput.git", + "xmlhttprequest": "~1.6.0" }, "devDependencies": { "grunt-contrib-watch": "latest", diff --git a/public/css/common.css b/public/css/common.css index 4292fb3..f84e5a6 100644 --- a/public/css/common.css +++ b/public/css/common.css @@ -278,6 +278,11 @@ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { overflow: hidden; } +#footer .currency a:active { + color: #fff; + text-decoration: underline; +} + #footer a.insight { font-size: 20px; text-decoration: none; diff --git a/public/js/app.js b/public/js/app.js index ba71dc8..279ea33 100755 --- a/public/js/app.js +++ b/public/js/app.js @@ -14,7 +14,8 @@ angular.module('insight',[ 'insight.address', 'insight.search', 'insight.status', - 'insight.connection' + 'insight.connection', + 'insight.currency' ]); angular.module('insight.system', []); @@ -25,3 +26,4 @@ angular.module('insight.address', []); angular.module('insight.search', []); angular.module('insight.status', []); angular.module('insight.connection', []); +angular.module('insight.currency', []); diff --git a/public/js/controllers/footer.js b/public/js/controllers/footer.js index 6aa1d87..8ad61ab 100644 --- a/public/js/controllers/footer.js +++ b/public/js/controllers/footer.js @@ -1,15 +1,62 @@ 'use strict'; angular.module('insight.system').controller('FooterController', - function($scope, Version) { + function($rootScope, $scope, Version, Currency) { - var _getVersion = function() { - Version.get({}, - function(res) { - $scope.version = res.version; - }); - }; + var _roundFloat = function(x, n) { + if(!parseInt(n, 10)) n = 0; - $scope.version = _getVersion(); + if(!parseFloat(x)) return false; + + return Math.round(x * Math.pow(10, n)) / Math.pow(10, n); + }; + + $rootScope.currency = { + factor: 1, + symbol: 'BTC', + bitstamp: 0, + getConversion: function(value) { + if (value !== 'undefined' && value !== null) { + var response; + + if (this.symbol === 'USD') { + response = _roundFloat((value * this.factor), 2); + } else if (this.symbol === 'mBTC') { + this.factor = 1000; + response = _roundFloat((value * this.factor), 5); + } else { + this.factor = 1; + response = value; + } + + return response + ' ' + this.symbol; + } + + return null; + } + }; + + $scope.setCurrency = function(currency) { + if (currency === 'USD') { + Currency.get({}, function(res) { + $rootScope.currency.factor = res.data.bitstamp; + }); + } else if (currency === 'mBTC') { + $rootScope.currency.factor = 1000; + } else { + $rootScope.currency.factor = 1; + } + + $rootScope.currency.symbol = currency; + }; + + var _getVersion = function() { + Version.get({}, + function(res) { + $scope.version = res.version; + }); + }; + + $scope.version = _getVersion(); }); diff --git a/public/js/controllers/header.js b/public/js/controllers/header.js index e5fa3ac..25f2d0b 100755 --- a/public/js/controllers/header.js +++ b/public/js/controllers/header.js @@ -1,9 +1,11 @@ 'use strict'; angular.module('insight.system').controller('HeaderController', - function($scope, $rootScope, getSocket, Global, Block) { + function($scope, $rootScope, getSocket, Global, Block, Currency) { $scope.global = Global; + Currency.get(); + $scope.menu = [ { 'title': 'Blocks', diff --git a/public/js/directives.js b/public/js/directives.js index 3bd91db..2d90b27 100755 --- a/public/js/directives.js +++ b/public/js/directives.js @@ -3,7 +3,7 @@ var ZeroClipboard = window.ZeroClipboard; angular.module('insight') - .directive('whenScrolled', ['$window', function($window) { + .directive('whenScrolled', function($window) { return { restric: 'A', link: function(scope, elm, attr) { @@ -21,13 +21,14 @@ angular.module('insight') }; $window.on('scroll', handler); + scope.$on('$destroy', function() { return $window.off('scroll', handler); }); } }; - }]) - .directive('clipCopy', [function() { + }) + .directive('clipCopy', function() { ZeroClipboard.config({ moviePath: '/lib/zeroclipboard/ZeroClipboard.swf', trustedDomains: ['*'], @@ -54,4 +55,4 @@ angular.module('insight') }); } }; - }]); + }); diff --git a/public/js/services/currency.js b/public/js/services/currency.js new file mode 100644 index 0000000..1a9cc0e --- /dev/null +++ b/public/js/services/currency.js @@ -0,0 +1,6 @@ +'use strict'; + +angular.module('insight.currency').factory('Currency', + function($resource) { + return $resource('/api/currency'); +}); diff --git a/public/views/includes/footer.html b/public/views/includes/footer.html index e87127e..5395a66 100644 --- a/public/views/includes/footer.html +++ b/public/views/includes/footer.html @@ -1,3 +1,9 @@
+
+ Currency: + USD - + BTC - + mBTC +
Insight API v{{version}}
diff --git a/public/views/transaction/tx.html b/public/views/transaction/tx.html index f3dc900..0b7062e 100644 --- a/public/views/transaction/tx.html +++ b/public/views/transaction/tx.html @@ -8,7 +8,7 @@
-
{{vin.reward}} BTC
+
{{$root.currency.getConversion(vin.reward)}}
No Inputs (Newly Generated Coins)
@@ -17,7 +17,7 @@
-
{{vin.value}} BTC
+
{{$root.currency.getConversion(vin.value)}}
{{vin.addr}} {{vin.addr}} @@ -27,7 +27,7 @@
-
{{vin.value}} BTC
+
{{$root.currency.getConversion(vin.value)}}
   {{vin.addr}} @@ -57,7 +57,7 @@
-
{{vout.value}} BTC
+
{{$root.currency.getConversion(vout.value)}}
{{vout.addr}} {{vout.addr}} @@ -67,7 +67,7 @@
-
{{vout.value}} BTC
+
{{$root.currency.getConversion(vout.value)}}
@@ -97,6 +97,6 @@
- +