2 lines
15 KiB
JavaScript
2 lines
15 KiB
JavaScript
/*! insight 0.0.1 */
|
|
"use strict";angular.module("insight",["ngAnimate","ngResource","ngRoute","ui.bootstrap","ui.route","monospaced.qrcode","insight.system","insight.socket","insight.blocks","insight.transactions","insight.address","insight.search","insight.status","insight.connection","insight.currency"]),angular.module("insight.system",[]),angular.module("insight.socket",[]),angular.module("insight.blocks",[]),angular.module("insight.transactions",[]),angular.module("insight.address",[]),angular.module("insight.search",[]),angular.module("insight.status",[]),angular.module("insight.connection",[]),angular.module("insight.currency",[]),angular.module("insight.address").controller("AddressController",function($scope,$rootScope,$routeParams,$location,Global,Address,getSocket){$scope.global=Global,$scope.findOne=function(){$rootScope.currentAddr=$routeParams.addrStr,Address.get({addrStr:$routeParams.addrStr},function(address){$rootScope.titleDetail=address.addrStr.substring(0,7)+"...",$scope.address=address},function(e){$rootScope.flashMessage=400===e.status?"Invalid Address: "+$routeParams.addrStr:503===e.status?"Backend Error. "+e.data:"Address Not Found",$location.path("/")})};var socket=getSocket($scope);socket.emit("subscribe",$routeParams.addrStr),socket.on($routeParams.addrStr,function(tx){console.log("AddressTx event received "+tx),$rootScope.$broadcast("tx",tx)}),$scope.params=$routeParams}),angular.module("insight.blocks").controller("BlocksController",function($scope,$rootScope,$routeParams,$location,Global,Block,Blocks,BlockByHeight){$scope.global=Global,$scope.loading=!1,$routeParams.blockHeight&&BlockByHeight.get({blockHeight:$routeParams.blockHeight},function(hash){$location.path("/block/"+hash.blockHash)},function(){$rootScope.flashMessage="Bad Request",$location.path("/")}),$scope.humanSince=function(time){var m=moment.unix(time).startOf("day"),b=moment().startOf("day");return m.max().from(b)},$scope.list=function(){$scope.loading=!0,$routeParams.blockDate&&($rootScope.titleDetail="on "+$routeParams.blockDate),Blocks.get({blockDate:$routeParams.blockDate},function(res){$scope.loading=!1,$scope.blocks=res.blocks,$scope.pagination=res.pagination})},$scope.findOne=function(){$scope.loading=!0,Block.get({blockHash:$routeParams.blockHash},function(block){$rootScope.titleDetail=block.height,$scope.loading=!1,$scope.block=block},function(e){$rootScope.flashMessage=400===e.status?"Invalid Transaction ID: "+$routeParams.txId:503===e.status?"Backend Error. "+e.data:"Block Not Found",$location.path("/")})},$scope.params=$routeParams}),angular.module("insight.connection").controller("ConnectionController",function($scope,$window,Status,Sync,getSocket){$scope.apiOnline=!0,$scope.serverOnline=!0,$scope.clienteOnline=!0;var socket=getSocket($scope);socket.on("disconnect",function(){$scope.serverOnline=!1}),socket.on("connect",function(){$scope.serverOnline=!0}),$scope.getConnStatus=function(){Sync.get({},function(sync){$scope.apiOnline="aborted"!==sync.status&&"error"!==sync.status},function(){$scope.apiOnline=!1})},socket.emit("subscribe","sync"),socket.on("status",function(sync){$scope.apiOnline="aborted"!==sync.status&&"error"!==sync.status}),$window.addEventListener("offline",function(){$scope.$apply(function(){$scope.clienteOnline=!1})},!0),$window.addEventListener("online",function(){$scope.$apply(function(){$scope.clienteOnline=!0})},!0)}),angular.module("insight.currency").controller("CurrencyController",function($scope,$rootScope,Currency){var _roundFloat=function(x,n){return parseInt(n,10)&&parseFloat(x)||(n=0),Math.round(x*Math.pow(10,n))/Math.pow(10,n)};$rootScope.currency.getConvertion=function(value){if("undefined"!=typeof value&&null!==value){var response;return"USD"===this.symbol?response=_roundFloat(value*this.factor,2):"mBTC"===this.symbol?(this.factor=1e3,response=_roundFloat(value*this.factor,5)):(this.factor=1,response=value),response+" "+this.symbol}return"value error"},$scope.setCurrency=function(currency){$rootScope.currency.symbol=currency,"USD"===currency?Currency.get({},function(res){$rootScope.currency.factor=$rootScope.currency.bitstamp=res.data.bitstamp}):$rootScope.currency.factor="mBTC"===currency?1e3:1},Currency.get({},function(res){$rootScope.currency.bitstamp=res.data.bitstamp})}),angular.module("insight.system").controller("FooterController",function($scope,Version){var _getVersion=function(){Version.get({},function(res){$scope.version=res.version})};$scope.version=_getVersion()}),angular.module("insight.system").controller("HeaderController",function($scope,$rootScope,getSocket,Global,Block){$scope.global=Global,$rootScope.currency={factor:1,bitstamp:0,symbol:"BTC"},$scope.menu=[{title:"Blocks",link:"blocks"},{title:"Status",link:"status"}];var socket=getSocket($scope);socket.emit("subscribe","inv");var _getBlock=function(hash){Block.get({blockHash:hash},function(res){$scope.totalBlocks=res.height})};socket.on("block",function(block){var blockHash=block.toString();console.log("Updated Blocks Height!"),_getBlock(blockHash)}),$rootScope.isCollapsed=!0});var TRANSACTION_DISPLAYED=5,BLOCKS_DISPLAYED=5;angular.module("insight.system").controller("IndexController",function($scope,$rootScope,Global,getSocket,Blocks,Transaction){$scope.global=Global;var _getBlocks=function(){Blocks.get({limit:BLOCKS_DISPLAYED},function(res){$scope.blocks=res.blocks,$scope.blocksLength=res.lenght})},_getTransaction=function(txid,cb){Transaction.get({txId:txid},function(res){cb(res)})},socket=getSocket($scope);socket.emit("subscribe","inv"),$scope.flashMessage=$rootScope.flashMessage||null,socket.on("tx",function(tx){console.log("Transaction received! "+JSON.stringify(tx));var txStr=tx.toString();_getTransaction(txStr,function(res){$scope.txs.unshift(res),parseInt($scope.txs.length,10)>=parseInt(TRANSACTION_DISPLAYED,10)&&($scope.txs=$scope.txs.splice(0,TRANSACTION_DISPLAYED))})}),socket.on("block",function(block){var blockHash=block.toString();console.log("Block received! "+JSON.stringify(blockHash)),_getBlocks()}),$scope.humanSince=function(time){var m=moment.unix(time);return m.max().fromNow()},$scope.index=function(){_getBlocks()},$scope.txs=[],$scope.blocks=[]}),angular.module("insight.search").controller("SearchController",function($scope,$routeParams,$location,$timeout,Global,Block,Transaction,Address,BlockByHeight){$scope.global=Global;var _badQuery=function(){$scope.badQuery=!0,$timeout(function(){$scope.badQuery=!1},2e3)};$scope.search=function(){var q=$scope.q;$scope.badQuery=!1,Block.get({blockHash:q},function(){$scope.q="",$location.path("block/"+q)},function(){Transaction.get({txId:q},function(){$scope.q="",$location.path("tx/"+q)},function(){Address.get({addrStr:q},function(){$scope.q="",$location.path("address/"+q)},function(){isFinite(q)?BlockByHeight.get({blockHeight:q},function(hash){$scope.q="",$location.path("/block/"+hash.blockHash)},function(){_badQuery()}):_badQuery()})})})}}),angular.module("insight.status").controller("StatusController",function($scope,$routeParams,$location,Global,Status,Sync,getSocket){$scope.global=Global,$scope.getStatus=function(q){Status.get({q:"get"+q},function(d){$scope.loaded=1,angular.extend($scope,d)},function(e){$scope.error="API ERROR: "+e.data})};var _onSyncUpdate=function(sync){$scope.sync=sync};$scope.getSync=function(){Sync.get({},function(sync){_onSyncUpdate(sync)},function(e){var err="Could not get sync information"+e.toString();$scope.sync={error:err}})};var socket=getSocket($scope);socket.emit("subscribe","sync"),socket.on("status",function(sync){_onSyncUpdate(sync)})}),angular.module("insight.transactions").controller("transactionsController",function($scope,$rootScope,$routeParams,$location,Global,Transaction,TransactionsByBlock,TransactionsByAddress){$scope.global=Global,$scope.loading=!1,$scope.loadedBy=null;var pageNum=0,pagesTotal=1,COIN=1e8,_aggregateItems=function(items){if(!items)return[];for(var l=items.length,ret=[],tmp={},u=0,i=0;l>i;i++){var notAddr=!1;if(items[i].scriptSig&&!items[i].addr&&(items[i].addr="Unparsed address ["+u++ +"]",items[i].notAddr=!0,notAddr=!0),items[i].scriptPubKey&&!items[i].scriptPubKey.addresses&&(items[i].scriptPubKey.addresses=["Unparsed address ["+u++ +"]"],items[i].notAddr=!0,notAddr=!0),items[i].scriptPubKey&&items[i].scriptPubKey.addresses.length>1)items[i].addr=items[i].scriptPubKey.addresses.join(","),ret.push(items[i]);else{var addr=items[i].addr||items[i].scriptPubKey&&items[i].scriptPubKey.addresses[0];tmp[addr]||(tmp[addr]={},tmp[addr].valueSat=0,tmp[addr].count=0,tmp[addr].addr=addr,tmp[addr].items=[]),tmp[addr].valueSat+=items[i].value*COIN,tmp[addr].value=items[i].value,tmp[addr].items.push(items[i]),tmp[addr].notAddr=notAddr,tmp[addr].count++}}return angular.forEach(tmp,function(v){ret.push(v)}),ret},_processTX=function(tx){tx.vinSimple=_aggregateItems(tx.vin),tx.voutSimple=_aggregateItems(tx.vout)},_paginate=function(data){$scope.loading=!1,pagesTotal=data.pagesTotal,pageNum+=1,data.txs.forEach(function(tx){_processTX(tx),$scope.txs.push(tx)})},_byBlock=function(){TransactionsByBlock.get({block:$routeParams.blockHash,pageNum:pageNum},function(data){_paginate(data)})},_byAddress=function(){TransactionsByAddress.get({address:$routeParams.addrStr,pageNum:pageNum},function(data){_paginate(data)})},_findTx=function(txid){Transaction.get({txId:txid},function(tx){$rootScope.titleDetail=tx.txid.substring(0,7)+"...",$scope.tx=tx,_processTX(tx),$scope.txs.unshift(tx)},function(e){$rootScope.flashMessage=400===e.status?"Invalid Transaction ID: "+$routeParams.txId:503===e.status?"Backend Error. "+e.data:"Transaction Not Found",$location.path("/")})};$scope.findThis=function(){_findTx($routeParams.txId)},$scope.load=function(from){$scope.loadedBy=from,$scope.loadMore()},$scope.loadMore=function(){pagesTotal>pageNum&&!$scope.loading&&($scope.loading=!0,"address"===$scope.loadedBy?_byAddress():_byBlock())},$scope.txs=[],$scope.$on("tx",function(event,txid){_findTx(txid)})}),angular.module("insight.address").factory("Address",function($resource){return $resource("/api/addr/:addrStr",{addrStr:"@addStr"},{get:{method:"GET",interceptor:{response:function(res){return res.data},responseError:function(res){return 404===res.status?res:void 0}}}})}),angular.module("insight.blocks").factory("Block",function($resource){return $resource("/api/block/:blockHash",{blockHash:"@blockHash"},{get:{method:"GET",interceptor:{response:function(res){return res.data},responseError:function(res){return 404===res.status?res:void 0}}}})}).factory("Blocks",function($resource){return $resource("/api/blocks")}).factory("BlockByHeight",function($resource){return $resource("/api/block-index/:blockHeight")}),angular.module("insight.currency").factory("Currency",function($resource){return $resource("/api/currency")}),angular.module("insight.system").factory("Global",[function(){}]).factory("Version",function($resource){return $resource("/api/version")});var ScopedSocket=function(socket,$rootScope){this.socket=socket,this.$rootScope=$rootScope,this.listeners=[]};ScopedSocket.prototype.removeAllListeners=function(){for(var i=0;i<this.listeners.length;i++){var details=this.listeners[i];this.socket.removeListener(details.event,details.fn)}this.listeners=[]},ScopedSocket.prototype.on=function(event,callback){var socket=this.socket,$rootScope=this.$rootScope,wrapped_callback=function(){var args=arguments;$rootScope.$apply(function(){callback.apply(socket,args)})};socket.on(event,wrapped_callback),this.listeners.push({event:event,fn:wrapped_callback})},ScopedSocket.prototype.emit=function(event,data,callback){var socket=this.socket,$rootScope=this.$rootScope;socket.emit(event,data,function(){var args=arguments;$rootScope.$apply(function(){callback&&callback.apply(socket,args)})})},angular.module("insight.socket").factory("getSocket",function($rootScope){var socket=io.connect();return function(scope){var scopedSocket=new ScopedSocket(socket,$rootScope);return scope.$on("$routeChangeStart",function(){}),scope.$on("$destroy",function(){scopedSocket.removeAllListeners()}),scopedSocket}}),angular.module("insight.status").factory("Status",function($resource){return $resource("/api/status",{q:"@q"})}).factory("Sync",function($resource){return $resource("/api/sync")}),angular.module("insight.transactions").factory("Transaction",function($resource){return $resource("/api/tx/:txId",{txId:"@txId"},{get:{method:"GET",interceptor:{response:function(res){return res.data},responseError:function(res){return 404===res.status?res:void 0}}}})}).factory("TransactionsByBlock",function($resource){return $resource("/api/txs",{block:"@block"})}).factory("TransactionsByAddress",function($resource){return $resource("/api/txs",{address:"@address"})}).factory("Transactions",function($resource){return $resource("/api/txs")});var ZeroClipboard=window.ZeroClipboard;angular.module("insight").directive("whenScrolled",function($window){return{restric:"A",link:function(scope,elm,attr){var pageHeight,clientHeight,scrollPos;$window=angular.element($window);var handler=function(){pageHeight=window.document.documentElement.scrollHeight,clientHeight=window.document.documentElement.clientHeight,scrollPos=window.pageYOffset,pageHeight-(scrollPos+clientHeight)===0&&scope.$apply(attr.whenScrolled)};$window.on("scroll",handler),scope.$on("$destroy",function(){return $window.off("scroll",handler)})}}}).directive("clipCopy",function(){return ZeroClipboard.config({moviePath:"/lib/zeroclipboard/ZeroClipboard.swf",trustedDomains:["*"],allowScriptAccess:"always",forceHandCursor:!0}),{restric:"A",scope:{clipCopy:"=clipCopy"},template:'<span class="glyphicon glyphicon-paperclip"></span><div class="tooltip fade right in"><div class="tooltip-arrow"></div><div class="tooltip-inner">Copied!</div></div>',link:function(scope,elm){var clip=new ZeroClipboard(elm);clip.on("load",function(client){var onMousedown=function(client){client.setText(scope.clipCopy)};client.on("mousedown",onMousedown),client.on("noflash wrongflash",function(){return elm.remove()}),scope.$on("$destroy",function(){client.off("mousedown",onMousedown)})})}}}),angular.module("insight").config(function($routeProvider){$routeProvider.when("/block/:blockHash",{templateUrl:"/views/block.html",title:"Bitcoin Block "}).when("/block-index/:blockHeight",{controller:"BlocksController",templateUrl:"/views/redirect.html"}).when("/tx/:txId",{templateUrl:"/views/transaction.html",title:"Bitcoin Transaction "}).when("/",{templateUrl:"/views/index.html",title:"Home"}).when("/blocks",{templateUrl:"/views/block_list.html",title:"Bitcoin Blocks solved Today"}).when("/blocks-date/:blockDate",{templateUrl:"/views/block_list.html",title:"Bitcoin Blocks solved "}).when("/address/:addrStr",{templateUrl:"/views/address.html",title:"Bitcoin Address "}).when("/status",{templateUrl:"/views/status.html",title:"Status"}).otherwise({templateUrl:"/views/404.html",title:"Error"})}),angular.module("insight").config(function($locationProvider){$locationProvider.html5Mode(!0),$locationProvider.hashPrefix("!")}).run(function($rootScope,$route){$rootScope.$on("$routeChangeSuccess",function(){$rootScope.titleDetail="",$rootScope.title=$route.current.title,$rootScope.isCollapsed=!0,$rootScope.currentAddr=null})}),angular.element(document).ready(function(){}); |