Created
September 13, 2016 16:04
-
-
Save vcealicu/ff81da5d2d7e599337ade5a2efb57dba to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module('ccc-app').factory('socketWrapper',['$rootScope','$interval', function socketWrapperFactory($rootScope,$interval) { | |
//none of the streamer controllers will actually update the intrace so i use this interval function to do the updates.... | |
//i specifically prohibit it from calling scope apply at the end because i am calling it inside... did this to make | |
//easier to understand what it does. | |
$interval(function() {$rootScope.$apply();}, 200,0,false); | |
return io.connect('https://streamer.cryptocompare.com/', {secure: true}); | |
}]); | |
angular.module('ccc-app').factory('streamerUtilities',['$rootScope','$filter','socketWrapper','subscriptionManager', | |
function streamerUtilitiesFactory($rootScope,$filter,socketWrapper,subscriptionManager){ | |
// CCC.CURRENT.DISPLAY.FIELDS is decalred in streaming-utilies global. | |
// CCC.TRADE.DISPLAY.FIELDS is decalred in streaming-utilies global. | |
var displaySettings = CCC.CURRENT.DISPLAY.FIELDS; | |
var tradeDisplaySettings = CCC.TRADE.DISPLAY.FIELDS; | |
var displayCurrency = CCC.STATIC.CURRENCY; | |
var utilStatic = CCC.STATIC.UTIL; | |
var isStreaming = true; | |
var isConnected = false; | |
var alreadyStopped =false; | |
var globalPageSubs = {}; | |
var streamerUtilitiesInstance = {}; | |
var cachedMessages = {}; | |
var aggPreLoaded = false; | |
var monitorPreLoaded = false; | |
socketWrapper.on('connect', function (data) { | |
isConnected =true; | |
$rootScope.$emit("SocketConnected",true); | |
}); | |
socketWrapper.on('reconnect', function () { | |
if(!isConnected){ | |
isConnected=true; | |
$rootScope.$emit("SocketConnected",true); | |
}else{ | |
} | |
}); | |
socketWrapper.on('reconnecting', function () { | |
if(isConnected){ | |
globalPageSubs = {}; | |
isConnected =false; | |
} | |
}); | |
socketWrapper.on('m', function (message) { | |
var messageType = message.substring(0, message.indexOf("~")); | |
switch(messageType){ | |
case CCC.STATIC.TYPE.TRADE: | |
streamerUtilitiesInstance.emitCurrentTrade('TradeMessage',message); | |
break; | |
case CCC.STATIC.TYPE.CURRENT: | |
streamerUtilitiesInstance.emitCurrentMessage('CurrentMessage',message); | |
break; | |
case CCC.STATIC.TYPE.CURRENTAGG: | |
streamerUtilitiesInstance.emitCurrentMessage('CurrentAggMessage',message); | |
break; | |
case CCC.STATIC.TYPE.ORDERBOOK: | |
console.log(message); | |
break; | |
case CCC.STATIC.TYPE.ORDERBOOKCLEAR: | |
console.log(message); | |
break; | |
case CCC.STATIC.TYPE.LOADCOMPLATE: | |
if(!isStreaming && !alreadyStopped){ | |
streamerUtilitiesInstance.stopStreaming(); | |
alreadyStopped = true; | |
} | |
break; | |
} | |
}); | |
streamerUtilitiesInstance.getStreamingStatus = function(){ | |
return isStreaming; | |
}; | |
streamerUtilitiesInstance.stopStreaming = function (){ | |
var subsToSend = []; | |
for (var sub in globalPageSubs) { | |
if (globalPageSubs.hasOwnProperty(sub)) { | |
subsToSend.push(sub); | |
} | |
} | |
if(subsToSend.length>0){ | |
socketWrapper.emit('SubRemove',{subs:subsToSend} ); | |
isStreaming = false; | |
return true; | |
} | |
return false; | |
}; | |
streamerUtilitiesInstance.startStreaming = function (){ | |
var subsToSend = []; | |
if(isStreaming){return false;} | |
for (var sub in globalPageSubs) { | |
if (globalPageSubs.hasOwnProperty(sub)) { | |
subsToSend.push(sub); | |
} | |
} | |
if(subsToSend.length>0){ | |
socketWrapper.emit('SubAdd',{subs:subsToSend} ); | |
isStreaming = true; | |
return true; | |
} | |
return false; | |
}; | |
streamerUtilitiesInstance.addGlobalPageSubs = function (subs,callback){ | |
var subsToSend = []; | |
for(var i=0;i<subs.length;i++){ | |
if(globalPageSubs.hasOwnProperty(subs[i])){ | |
globalPageSubs[subs[i]] = globalPageSubs[subs[i]]+1; | |
if(cachedMessages.hasOwnProperty(subs[i])){ | |
callback(cachedMessages[subs[i]]); | |
} | |
}else{ | |
globalPageSubs[subs[i]] = 1; | |
subsToSend.push(subs[i]); | |
if(cachedMessages.hasOwnProperty(subs[i])){ | |
callback(cachedMessages[subs[i]]); | |
} | |
} | |
} | |
if(subsToSend.length>0){ | |
socketWrapper.emit('SubAdd',{subs:subsToSend} ); | |
} | |
alreadyStopped = false; | |
}; | |
streamerUtilitiesInstance.removeGlobalPageSubs = function (subs){ | |
var subsToRemove = []; | |
for(var i=0;i<subs.length;i++){ | |
if(globalPageSubs.hasOwnProperty(subs[i])){ | |
globalPageSubs[subs[i]] = globalPageSubs[subs[i]]-1; | |
if(globalPageSubs[subs[i]]==0){ | |
subsToRemove.push(subs[i]); | |
delete globalPageSubs[subs[i]]; | |
} | |
} | |
} | |
if(subsToRemove.length>0){ | |
socketWrapper.emit('SubRemove',{subs:subsToRemove} ); | |
} | |
}; | |
streamerUtilitiesInstance.initConnection = function(){ | |
return { | |
connected : isConnected, | |
loadingData : true, | |
aggPreLoaded : aggPreLoaded, | |
monitorPreLoaded : monitorPreLoaded, | |
subs : [], | |
data : [], | |
orderBookData : {}, | |
keyToPosition : {}, | |
totalvolume24hour : 0 | |
}; | |
}; | |
streamerUtilitiesInstance.initProgressBar = function(){ | |
if(isConnected){ | |
return { | |
current : 2, | |
message : 'Loading data...', | |
max : 3 | |
}; | |
}else{ | |
return { | |
current : 1, | |
message : 'Connecting...', | |
max : 3 | |
}; | |
} | |
}; | |
streamerUtilitiesInstance.initOrdering = function(){ | |
return { | |
isAscending : false, | |
sortingField : '' | |
}; | |
}; | |
streamerUtilitiesInstance.emitCurrentTrade = function(messageType,messageRaw){ | |
var currentTrade = CCC.TRADE.unpack(messageRaw); | |
var subKey = CCC.TRADE.getKey(currentTrade); | |
var currentDisplay = {}; | |
for(var property in currentTrade){ | |
if(tradeDisplaySettings[property].Show){ | |
switch(tradeDisplaySettings[property].Filter){ | |
case 'Date': | |
currentDisplay[property] = $filter('date')(currentTrade[property]*1000, tradeDisplaySettings[property].Format); | |
break; | |
case 'Number': | |
var symbolType = tradeDisplaySettings[property].Symbol; | |
currentDisplay[property] = utilStatic.convertValueToDisplay(currentDisplay[symbolType],currentTrade[property],$filter('number')); | |
break; | |
case 'Text': | |
currentDisplay[property] = currentTrade[property]; | |
break; | |
case 'CurrencySymbol': | |
currentDisplay[property] = displayCurrency.getSymbol(currentTrade[property]); | |
break; | |
case 'Market': | |
currentDisplay[property] = subscriptionManager.getNameForExchange(currentTrade[property]); | |
break | |
case 'TradeFlag': | |
if(parseInt(currentTrade[property],16)&CCC.TRADE.FLAGS.SELL){ | |
currentDisplay[property] ='Sell'; | |
}else if (parseInt(currentTrade[property],16)&CCC.TRADE.FLAGS.BUY){ | |
currentDisplay[property] ='Buy'; | |
}else{ | |
currentDisplay[property] ='Unknown'; | |
} | |
break; | |
} | |
} | |
} | |
currentTrade['ARRIVEDON'] = new Date(); | |
currentTrade['highlight'] = true; | |
currentTrade['DISPLAY'] = currentDisplay; | |
var messageToEmit ={}; | |
messageToEmit.Raw = messageRaw; | |
messageToEmit.SubKey = subKey; | |
messageToEmit.Obj = currentTrade; | |
$rootScope.$emit(messageType,messageToEmit); | |
}; | |
streamerUtilitiesInstance.mergeObjects = function(obj1,obj2){ | |
for(var attrname in obj2){ obj1[attrname] = obj2[attrname]; } | |
return obj1; | |
} | |
streamerUtilitiesInstance.copyObject = function(obj1){ | |
var obj2={}; | |
for(var attrname in obj1){ obj1[attrname] = obj2[attrname]; } | |
return obj2; | |
} | |
streamerUtilitiesInstance.decorateCurrent = function(prevMessage,newMessage){ | |
//fields that hard coded and should not be overwritten anywhere! | |
prevMessage = prevMessage||{}; | |
prevMessage['SUBKEY'] = prevMessage['SUBKEY']||newMessage.SubKey; | |
prevMessage['DATA'] = newMessage.Obj; | |
prevMessage['DISPLAY'] = newMessage.Display; | |
if(prevMessage['VISUAL']){ | |
prevMessage['VISUAL'] = streamerUtilitiesInstance.mergeObjects(prevMessage['VISUAL'],newMessage.Visual); | |
}else{ | |
prevMessage['VISUAL'] = newMessage.Visual; | |
} | |
return prevMessage; | |
}; | |
streamerUtilitiesInstance.decorateCurrentPorfolioMember = function(prevMessage,newMessage,type,portfolioCurrency){ | |
//fields that hard coded and should not be overwritten anywhere! | |
var dateNow = new Date(); | |
var animationExpires = dateNow.setMilliseconds(dateNow.getMilliseconds() + 900); | |
prevMessage.PriceInfo[type].RAW = newMessage.Obj; | |
prevMessage.PriceInfo[type].DISPLAY = newMessage.Display; | |
var currentPrice = newMessage.Obj.PRICE; | |
var currentOpen = newMessage.Obj.OPEN24HOUR; | |
var lastUpdate = newMessage.Obj.LASTUPDATE; | |
var displaySymbol = displayCurrency.getSymbol(portfolioCurrency); | |
var isRealatedToConversion = false; | |
prevMessage.PriceInfo.PortfolioValues.RAW.LastUpdate = lastUpdate; | |
switch(type){ | |
case 'Current': | |
prevMessage.PriceInfo.PortfolioValues.RAW.Price = currentPrice; | |
prevMessage.PriceInfo.PortfolioValues.RAW.Open24Hour = currentOpen; | |
break; | |
case 'Conversion': | |
if(prevMessage.PriceInfo.BTC.RAW.hasOwnProperty('PRICE')){ | |
currentPrice = currentPrice*prevMessage.PriceInfo.BTC.RAW.PRICE; | |
prevMessage.PriceInfo.PortfolioValues.RAW.Price = currentPrice; | |
} | |
if(prevMessage.PriceInfo.BTC.RAW.hasOwnProperty('OPEN24HOUR')){ | |
currentOpen = currentOpen*prevMessage.PriceInfo.BTC.RAW.OPEN24HOUR; | |
prevMessage.PriceInfo.PortfolioValues.RAW.Open24Hour = currentOpen; | |
} | |
break; | |
case 'BTC': | |
if(prevMessage.PriceInfo.Conversion.RAW.hasOwnProperty('PRICE')){ | |
currentPrice = currentPrice*prevMessage.PriceInfo.Conversion.RAW.PRICE; | |
prevMessage.PriceInfo.PortfolioValues.RAW.Price = currentPrice; | |
} | |
if(prevMessage.PriceInfo.Conversion.RAW.hasOwnProperty('OPEN24HOUR')){ | |
currentOpen = currentOpen*prevMessage.PriceInfo.Conversion.RAW.OPEN24HOUR; | |
prevMessage.PriceInfo.PortfolioValues.RAW.Open24Hour = currentOpen; | |
} | |
break; | |
case 'CurrentBuy': | |
prevMessage.PriceInfo.PortfolioValues.RAW.BuyConversionPrice = currentPrice; | |
prevMessage.PriceInfo.PortfolioValues.RAW.BuyConversionOpen24Hour = currentOpen; | |
isRealatedToConversion=true; | |
break; | |
case 'ConversionBuy': | |
if(prevMessage.PriceInfo.BTCBuy.hasOwnProperty('PRICE')){ | |
currentPrice = currentPrice*prevMessage.PriceInfo.BTCBuy.RAW.PRICE; | |
prevMessage.PriceInfo.PortfolioValues.RAW.BuyConversionPrice = currentPrice; | |
isRealatedToConversion=true; | |
} | |
if(prevMessage.PriceInfo.BTCBuy.hasOwnProperty('OPEN24HOUR')){ | |
currentOpen = currentOpen*prevMessage.PriceInfo.BTCBuy.RAW.OPEN24HOUR; | |
prevMessage.PriceInfo.PortfolioValues.RAW.BuyConversionOpen24Hour = currentOpen; | |
isRealatedToConversion=true; | |
} | |
break; | |
case 'BTCBuy': | |
if(prevMessage.PriceInfo.ConversionBuy.RAW.hasOwnProperty('PRICE')){ | |
currentPrice = currentPrice*prevMessage.PriceInfo.ConversionBuy.RAW.PRICE; | |
prevMessage.PriceInfo.PortfolioValues.RAW.BuyConversionPrice = currentPrice; | |
isRealatedToConversion=true; | |
} | |
if(prevMessage.PriceInfo.ConversionBuy.RAW.hasOwnProperty('OPEN24HOUR')){ | |
currentOpen = currentOpen*prevMessage.PriceInfo.ConversionBuy.RAW.OPEN24HOUR; | |
prevMessage.PriceInfo.PortfolioValues.RAW.BuyConversionOpen24Hour = currentOpen; | |
isRealatedToConversion=true; | |
} | |
break; | |
} | |
if(isRealatedToConversion==false){ | |
var newVisual = streamerUtilitiesInstance.copyObject(prevMessage.PriceInfo.Visual); | |
prevMessage.PriceInfo.Visual = streamerUtilitiesInstance.mergeObjects(newVisual,newMessage.Visual); | |
}else{ | |
prevMessage.PriceInfo.Visual.CONVERSIONBUY = animationExpires; | |
} | |
return prevMessage; | |
}; | |
streamerUtilitiesInstance.decorateCurrentWithMktCap = function(prevMessage,newMessage,totalCoinsMined){ | |
//fields that hard coded and should not be overwritten anywhere! | |
prevMessage = prevMessage||{}; | |
prevMessage['SUBKEY'] = prevMessage['SUBKEY']||newMessage.SubKey; | |
prevMessage['DATA'] = newMessage.Obj; | |
prevMessage['DISPLAY'] = newMessage.Display; | |
prevMessage.DATA.MKTCAP = 0; | |
prevMessage.DISPLAY.MKTCAP = "N/A"; | |
if(totalCoinsMined!=0){ | |
prevMessage.DATA.MKTCAP = prevMessage['DATA'].PRICE*totalCoinsMined; | |
prevMessage.DISPLAY.MKTCAP = utilStatic.convertValueToDisplay(prevMessage.DISPLAY.TOSYMBOL,prevMessage.DATA.MKTCAP,$filter('number'),'short'); | |
} | |
if(prevMessage['VISUAL']){ | |
prevMessage['VISUAL'] = streamerUtilitiesInstance.mergeObjects(prevMessage['VISUAL'],newMessage.Visual); | |
}else{ | |
prevMessage['VISUAL'] = newMessage.Visual; | |
} | |
return prevMessage; | |
}; | |
streamerUtilitiesInstance.decorateMktCap = function(messageInfo,totalCoinsMined){ | |
//fields that hard coded and should not be overwritten anywhere! | |
var messageToReturn = {}; | |
messageToReturn.DATA={}; | |
messageToReturn.DISPLAY={}; | |
var currentPrice = messageInfo.Obj.PRICE; | |
var displaySymbol = messageInfo.Display.TOSYMBOL; | |
messageToReturn.DATA.PRICE = currentPrice; | |
messageToReturn.DATA.MKTCAP = 0; | |
messageToReturn.DISPLAY.PRICE = utilStatic.convertValueToDisplay(displaySymbol,currentPrice,$filter('number')); | |
messageToReturn.DISPLAY.MKTCAP = "Not Available"; | |
if(totalCoinsMined!=0){ | |
messageToReturn.DATA.MKTCAP = currentPrice*totalCoinsMined; | |
messageToReturn.DISPLAY.MKTCAP = utilStatic.convertValueToDisplay(displaySymbol,messageToReturn.DATA.MKTCAP,$filter('number'),'short'); | |
} | |
return messageToReturn; | |
}; | |
streamerUtilitiesInstance.decorateCurrenyMktShare = function(messageInfo,totalVolume){ | |
//fields that hard coded and should not be overwritten anywhere! | |
var messageToReturn = {}; | |
messageToReturn.DATA={}; | |
messageToReturn.DISPLAY={}; | |
var volumeForm = messageInfo.Obj.VOLUME24HOUR; | |
var volumeTo = messageInfo.Obj.VOLUME24HOURTO; | |
var displayToSymbol = messageInfo.Display.TOSYMBOL; | |
var displayFromSymbol = messageInfo.Display.FROMSYMBOL; | |
messageToReturn.DATA.VOLUME24HOUR = volumeForm; | |
messageToReturn.DATA.VOLUME24HOURTO = volumeTo; | |
messageToReturn.DISPLAY.VOLUME24HOUR = utilStatic.convertValueToDisplay(displayFromSymbol,volumeForm,$filter('number')); | |
messageToReturn.DISPLAY.VOLUME24HOURTO = utilStatic.convertValueToDisplay(displayToSymbol,volumeTo,$filter('number')); | |
messageToReturn.DISPLAY.TOSYMBOL = displayToSymbol; | |
messageToReturn.DISPLAY.FROMSYMBOL = displayFromSymbol; | |
return messageToReturn; | |
}; | |
streamerUtilitiesInstance.initMonitorFromServer = function(rawDataArray){ | |
for(var i=0,length=rawDataArray.length;i<length;i++){ | |
streamerUtilitiesInstance.emitCurrentMessage('CurrentMessage',rawDataArray[i]); | |
} | |
monitorPreLoaded=true; | |
}; | |
streamerUtilitiesInstance.initAggFromServer = function(rawDataArray){ | |
for(var i=0,length=rawDataArray.length;i<length;i++){ | |
streamerUtilitiesInstance.emitCurrentMessage('CurrentAggMessage',rawDataArray[i]); | |
} | |
aggPreLoaded=true; | |
}; | |
streamerUtilitiesInstance.emitCurrentMessage = function(messageType,messageRaw){ | |
var lastestMessage= CCC.CURRENT.unpack(messageRaw); | |
var subKey = CCC.CURRENT.getKey(lastestMessage); | |
var dateNow = new Date(); | |
var animationExpires = dateNow.setMilliseconds(dateNow.getMilliseconds() + 900); | |
var currentMessageFull = cachedMessages[subKey] || {}; | |
var currentMessage = currentMessageFull['Obj']||{}; | |
var currentDisplay = currentMessageFull['Display']||{}; | |
var currentVisual = {}; | |
currentDisplay.FROMSYMBOL = displayCurrency.getSymbol(lastestMessage.FROMSYMBOL); | |
currentDisplay.TOSYMBOL = displayCurrency.getSymbol(lastestMessage.TOSYMBOL); | |
for(var flag in CCC.CURRENT.FLAGS){ | |
if(parseInt(lastestMessage['FLAGS'],16)&CCC.CURRENT.FLAGS[flag]){ | |
currentVisual[flag] = animationExpires; | |
} | |
} | |
for(var property in lastestMessage){ | |
currentMessage[property] = lastestMessage[property]; | |
if(displaySettings[property].Show){ | |
currentVisual[property] = animationExpires; | |
switch(displaySettings[property].Filter){ | |
case 'Date': | |
currentDisplay[property] = $filter('date')(lastestMessage[property]*1000, displaySettings[property].Format); | |
break; | |
case 'Number': | |
var symbolType = displaySettings[property].Symbol; | |
currentDisplay[property] = utilStatic.convertValueToDisplay(currentDisplay[symbolType],lastestMessage[property],$filter('number')); | |
break; | |
case 'String': | |
currentDisplay[property] = lastestMessage[property]; | |
break; | |
case 'Market': | |
currentDisplay[property] = subscriptionManager.getNameForExchange(lastestMessage[property]); | |
break | |
} | |
} | |
} | |
var newCHANGE24HOUR = currentMessage.PRICE - currentMessage.OPEN24HOUR; | |
currentVisual.CHANGE24HOUR = animationExpires; | |
currentMessage.CHANGE24HOUR = newCHANGE24HOUR; | |
currentMessage.CHANGEPCT24HOUR = currentMessage.CHANGE24HOUR/currentMessage.OPEN24HOUR*100; | |
if(Math.abs(currentMessage.CHANGE24HOUR)>10000){ | |
currentDisplay.CHANGE24HOUR = currentDisplay.TOSYMBOL+' '+$filter('number')(currentMessage.CHANGE24HOUR,0); | |
}else if(Math.abs(currentMessage.CHANGE24HOUR)>1){ | |
currentDisplay.CHANGE24HOUR = currentDisplay.TOSYMBOL+' '+$filter('number')(currentMessage.CHANGE24HOUR,2); | |
}else{ | |
currentDisplay.CHANGE24HOUR = currentDisplay.TOSYMBOL+' '+currentMessage.CHANGE24HOUR.toPrecision(2); | |
} | |
currentDisplay.CHANGEPCT24HOUR = $filter('number')(currentMessage.CHANGEPCT24HOUR,2); | |
if(currentMessage.CHANGE24HOUR>0){ | |
currentDisplay.CHANGE24HOURUP = animationExpires; | |
currentDisplay.CHANGE24HOURUNCHANGED = false; | |
currentDisplay.CHANGE24HOURDOWN = false; | |
}else if(currentMessage.CHANGE24HOUR<0){ | |
currentDisplay.CHANGE24HOURDOWN = animationExpires; | |
currentDisplay.CHANGE24HOURUNCHANGED = false; | |
currentDisplay.CHANGE24HOURUP = false; | |
}else{ | |
currentDisplay.CHANGE24HOURUNCHANGED = animationExpires; | |
currentDisplay.CHANGE24HOURDOWN = false; | |
currentDisplay.CHANGE24HOURUP = false; | |
} | |
var messageToEmit ={}; | |
messageToEmit.Raw = messageRaw; | |
messageToEmit.SubKey = subKey; | |
messageToEmit.Obj = currentMessage; | |
messageToEmit.Visual = currentVisual; | |
messageToEmit.Display = currentDisplay; | |
cachedMessages[subKey] = messageToEmit; | |
$rootScope.$emit(messageType,messageToEmit); | |
}; | |
return streamerUtilitiesInstance; | |
}]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment