Skip to content

Instantly share code, notes, and snippets.

@atomize
Last active October 16, 2018 17:39
Show Gist options
  • Save atomize/8e5037eab20b22a007775d62ce9aef4a to your computer and use it in GitHub Desktop.
Save atomize/8e5037eab20b22a007775d62ce9aef4a to your computer and use it in GitHub Desktop.
cccagg temp
let grouper;
const appInfo = {
aggSubs: [],
allSubs: [],
actualSubs: new Set(),
globalmenu: {},
imageUrls: new Map(),
pair: ["???", "???"]
};
const ccc = {
name: "ccc",
cccurl: "https://min-api.cryptocompare.com",
params: {
credentials: "omit",
headers: {},
referrer: "https://cryptoqween.github.io/streamer/trade/",
referrerPolicy: "no-referrer-when-downgrade",
body: null,
method: "GET",
mode: "cors"
},
coins: () => {
return fetch(`${ccc.cccurl}/data/all/coinlist`, this.params)
.then(res => res.json())
.then(data => data.Data);
},
exchanges: () => {
return fetch(`${ccc.cccurl}/data/all/exchanges`, this.params)
.then(res => res.json())
},
cccaggexchanges: () => {
return fetch(`${ccc.cccurl}/data/all/cccaggexchanges`, this.params)
.then(res => res.json())
},
subs: (...parameters) => {
return fetch(`${ccc.cccurl}/data/subs?fsym=${parameters[0]}`, this.params)
.then(res => res.json())
.then(res => {
return parameters.includes(1) ? res : subReducer(res);
});
}
};
const params = {
credentials: "omit",
headers: {},
referrer: "https://cryptoqween.github.io/streamer/trade/",
referrerPolicy: "no-referrer-when-downgrade",
body: null,
method: "GET",
mode: "cors"
};
const groupAlphaArray = rawData => {
let numtest = new RegExp(/[^A-Za-z]/);
let data = rawData.reduce((r, e) => {
let group = e.charAt(0).toUpperCase();
numtest.test(group) ? (group = "0-9") : group;
!r[group] ?
(r[group] = {
group,
children: [e]
}) :
r[group].children.push(e);
return r;
}, {});
return Object.values(data);
};
function showImage(list) {
let fragment = document.createDocumentFragment();
let container = document.getElementById("container");
list.forEach(function (element) {
let imgElem = document.createElement("img");
fragment.appendChild(imgElem);
imgElem.classList.add("grid-item");
imgElem.id = `${element[0]}`;
imgElem.style.height = "100px";
imgElem.style.width = "100px";
imgElem.src =
"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
imgElem.alt = `${element[0]}`;
imgElem.setAttribute("data-src", element[1]);
});
container.appendChild(fragment);
myLazyLoad = new LazyLoad({
container: container
});
}
const toggleSetVal = async (set, val) => {
if (set !== undefined) {
set.has(val) ? set.delete(val) : set.add(val);
}
};
function promiseMap(xs, f) {
const reducer = (ysAcc$, x) =>
ysAcc$.then(ysAcc =>
f(x).then(y => {
ysAcc[x] = y;
return ysAcc;
})
);
return xs.reduce(reducer, Promise.resolve({}));
}
function RateLimit(fn, delay, context) {
let queue = [],
timer = null;
function processQueue() {
let item = queue.shift();
if (item) fn.apply(item.context, item.arguments);
if (queue.length === 0) clearInterval(timer), (timer = null);
}
return function limited() {
queue.push({
context: context || this,
arguments: [].slice.call(arguments)
});
if (!timer) {
processQueue(); // start immediately on the first invocation
timer = setInterval(processQueue, delay);
}
};
}
function bigImg() {
let container = document.getElementById("container");
container.innerHTML = "";
showImage(unique(Array.from(appInfo.imageUrls)));
}
const union = (setA, setB) => {
let _union = new Set(setA);
for (let elem of setB) {
_union.add(elem);
}
return _union;
};
const unique = arr => [...new Set(arr)];
const uniqueFilter = (arr, zeroTwoOrFive) => {
return unique(arr.filter(bases => bases.split("~")[0] === zeroTwoOrFive));
};
const reducer = (a, c) =>
Array.isArray(c) || (typeof c === "object" && c !== null) ? [...a, ...c] : [...a, c];
const subReducer = res => {
let vals = Object.values(res);
vals[0] !== "Error" ?
(vals = vals
.flat()
.map(y => {
return Object.values(y).reduce(reducer);
})
.reduce(reducer)) :
(vals = []);
console.log("vals reduce: ", vals);
return vals;
};
const chunkArray = async (myArray, chunk_size) => {
let results = [];
while (myArray.length) {
results.push(myArray.splice(0, chunk_size));
}
return results;
};
const cccCoins = () =>
fetch("https://min-api.cryptocompare.com/data/all/coinlist", params).then(
res => res.json()
);
const cccSubs = (...parameters) => {
let fsym = parameters[0];
let dataUrl = "https://min-api.cryptocompare.com/data/subs?fsym=" + fsym;
return fetch(dataUrl, params)
.then(res => res.json())
.then(res => {
return parameters.includes(1) ? res : subReducer(res);
});
};
const cccaggOrCustom = () => {
if (appInfo.aggSubs !== undefined) {
if (
appInfo.aggSubs.size < appInfo.allSubs.size &&
appInfo.aggSubs.size !== 0
) {
updateOutput(2);
} else {
updateOutput(5);
}
}
};
const fsym = coin =>
cccSubs(coin).then(res => {
if (res.length !== 0) {
let menus = unique(makeMenus(res));
appInfo.globalmenu = menus;
appInfo.aggSubs = new Set(appInfo.globalmenu[4]);
appInfo.allSubs = new Set(appInfo.globalmenu[4]);
appInfo.pair = [coin, "???"];
fillMenu(menus[1], "tsym");
console.log(filtertest(menus[1]));
myLazyLoad.update();
updateOutput(5);
} else {
init(true);
}
});
const tsym = coin => {
filteredExs = unique(
appInfo.globalmenu[2]
.filter(x => x.match(coin))
.filter(x => x.includes("2~"))
.map(exchanges => exchanges.split("~")[1])
).sort();
appInfo.aggSubs = new Set(filteredExs);
appInfo.allSubs = new Set(filteredExs);
appInfo.pair[1] = coin;
updateOutput(5);
};
const fillMenu = (list, selector) => {
let subsSelect = document.getElementById(selector);
subsSelect.innerHTML = "";
let fragment = document.createDocumentFragment();
list.sort();
list.unshift("Select...");
list.map(function (element) {
let opt = document.createElement("option");
opt.value = element;
opt.innerHTML = element;
fragment.appendChild(opt);
});
subsSelect.appendChild(fragment);
};
const makeMenus = res => {
let exs5 = uniqueFilter(res, "5");
let exs2 = uniqueFilter(res, "2")
.map(exchanges => exchanges.split("~")[1])
.sort();
let exs0 = uniqueFilter(res, "0").map(exchanges => exchanges.split("~")[1]);
let menus = [
res[0].split("~")[2],
unique(res.map(bases => bases.split("~")[3])),
res,
exs5,
exs2,
exs0
];
return menus;
};
function filtertest(list) {
document.querySelectorAll("#container>img").forEach(imageEl => {
console.log(list.indexOf(imageEl.id));
return list.indexOf(imageEl.id) === -1 ?
imageEl.classList.add("hide") :
imageEl.classList.remove("hide");
});
}
const isChecked = lineEl => {
return appInfo.aggSubs.has(lineEl) ? "checked" : "";
};
const markupList = (lineEls, typeOf, delimiter = "") => {
let exchangemarkup = `<ul>
${lineEls
.map(
lineEl =>
`<li class='exchange-item'>
<input type = "checkbox"
class="exchange-checkbox"
name = "${lineEl}"
value ="${lineEl}"
${isChecked(lineEl)}>
${lineEl}
</li>`
)
.join(delimiter)}
</ul>`;
let subscriptionmarkup = `<ul>
${lineEls
.map(
lineEl =>
`<li class='subItem'>
${typeOf}~${lineEl}~${appInfo.pair[0]}~${appInfo.pair[1]}</li>`
)
.join(delimiter)}
</ul>`;
return typeOf === "exchange" ? exchangemarkup : subscriptionmarkup;
};
const updateOutput = (twoOrFive = 0) => {
if (twoOrFive === 5) {
document.getElementById("wsoutput2").innerHTML = `<ul><li>5~CCCAGG~${
appInfo.pair[0]
}~${appInfo.pair[1]}</li></ul>`;
} else {
document.getElementById("wsoutput2").innerHTML = markupList(
Array.from(appInfo.aggSubs).filter(x => x !== "Select..."),
twoOrFive
);
}
document.getElementById("exchanges").innerHTML = markupList(
Array.from(appInfo.allSubs).filter(x => x !== ("Select..." || "CCCAGG")),
"exchange"
);
};
const init = input => {
cccCoins().then(coins => {
["fsym", "tsym"].map(selectors => {
fillMenu(Object.keys(coins.Data), selectors);
});
appInfo.imageUrls = new Map(
Object.entries(coins.Data)
.reduce((a, c, i) => {
a[i] = [c[0], `https://www.cryptocompare.com${c[1].ImageUrl}`];
return a;
}, [])
.sort()
);
grouper = new Map(
groupAlphaArray([...appInfo.imageUrls.keys()]).reduce((a, c, i) => {
a[i] = [c.group, c.children];
return a;
}, [])
);
bigImg();
});
if (input) {
updateOutput(5);
}
};
const createSubscriptionStrings = () => {
appInfo.actualSubs = new Set();
appInfo.actualSubs = union(appInfo.actualSubs, appInfo.aggSubs);
appInfo.actualSubs = Array.from(appInfo.actualSubs).reduce((a, c) => {
a.push(`2~${c}~${appInfo.pair[0]}~${appInfo.pair[1]}`);
return a;
}, []);
return appInfo.actualSubs.length === appInfo.allSubs.size ?
(appInfo.actualSubs = [`5~CCCAGG~${appInfo.pair[0]}~${appInfo.pair[1]}`]) :
appInfo.actualSubs;
};
document.addEventListener("change", function () {
if (event.target instanceof HTMLSelectElement) {
if (event.target.id === "fsym") {
fsym(event.target.value);
}
if (event.target.id === "tsym") {
tsym(event.target.value);
}
}
});
document.addEventListener("mouseup", function () {
event.target instanceof HTMLInputElement &&
event.target.getAttribute("type") == "checkbox" ?
toggleSetVal(appInfo.aggSubs, event.target.value).then(cccaggOrCustom()) :
console.log("other mouse up, not a checkbox!");
if (event.target.classList.contains("exchange-item")) {
console.log(event.target.querySelector(".exchange-checkbox").checked);
}
if (event.target.classList.contains("subscribe")) {
if (appInfo.actualSubs.length > 0) {
removeSubs(appInfo.actualSubs);
}
createSubscriptionStrings();
addSubs(appInfo.actualSubs);
}
});
let socket = io.connect("https://streamer.cryptocompare.com/");
const addSubs = subsArr => {
socket.emit("SubAdd", {
subs: subsArr
});
};
const removeSubs = subsArr => {
socket.emit("SubRemove", {
subs: subsArr
});
};
socket.on("m", function (message) {
console.log(message);
});
init();
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js">
<!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>CryptoCompare Example</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
</head>
<body>
<h2>CryptoCompare WebSocket CURRENT VALUE</h2>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<div class="grid-container-4">
<div class="grid-item">
<div class="grid-container-2">
<div class="grid-item">
<label for="fsym">From Coin</label>
<br>
<select id="fsym">
<option value="">Loading...</option>
</select>
</div>
<div class="grid-item">
<label for="tsym">To Coin</label>
<br>
<select id="tsym">
<option value="">Loading...</option>
</select>
</div>
</div>
</div>
<div class="grid-item">
Aggregated Exchanges
<br>
<div id="exchanges">Loading...</div>
</div>
<div class="grid-item">
WS Subscription
<br>
<div id="wsoutput2">
</div>
</div>
<div class="grid-item">
<button class="subscribe">Subscribe</button>
<button class="addsub">Add to Sub</button>
<button class="unsubscribe">Unsubscribe All</button>
</div>
</div>
<div class="grid-container-4" id="container">
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.1/socket.io.slim.js'></script>
<script src="lazyload.min.js" async defer></script>
<script src="ccc.js" async defer></script>
</body>
</html>
var _extends=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(t[o]=n[o])}return t},_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};!function(t,e){"object"===("undefined"==typeof exports?"undefined":_typeof(exports))&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.LazyLoad=e()}(this,function(){"use strict";function t(t,e,n){return!(u(t,e,n)||_(t,e,n)||f(t,e,n)||h(t,e,n))}function e(t,e,n){var o=e._settings;!n&&r(t)||(C(o.callback_enter,t),R.indexOf(t.tagName)>-1&&(x(t,e),y(t,o.class_loading)),H(t,e),s(t),C(o.callback_set,t))}var n=function(){return{elements_selector:"img",container:window,threshold:300,throttle:150,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",class_loading:"loading",class_loaded:"loaded",class_error:"error",class_initial:"initial",skip_invisible:!0,callback_load:null,callback_error:null,callback_set:null,callback_enter:null,callback_finish:null,to_webp:!1}},o=function(t,e){return t.getAttribute("data-"+e)},i=function(t,e,n){var o="data-"+e;null!==n?t.setAttribute(o,n):t.removeAttribute(o)},s=function(t){return i(t,"was-processed","true")},r=function(t){return"true"===o(t,"was-processed")},l=function(t){return t.filter(function(t){return!r(t)})},a=function(t,e){return t.filter(function(t){return t!==e})},c=function(t){return t.getBoundingClientRect().top+window.pageYOffset-t.ownerDocument.documentElement.clientTop},u=function(t,e,n){return(e===window?window.innerHeight+window.pageYOffset:c(e)+e.offsetHeight)<=c(t)-n},d=function(t){return t.getBoundingClientRect().left+window.pageXOffset-t.ownerDocument.documentElement.clientLeft},f=function(t,e,n){var o=window.innerWidth;return(e===window?o+window.pageXOffset:d(e)+o)<=d(t)-n},_=function(t,e,n){return(e===window?window.pageYOffset:c(e))>=c(t)+n+t.offsetHeight},h=function(t,e,n){return(e===window?window.pageXOffset:d(e))>=d(t)+n+t.offsetWidth},p=function(t,e){var n,o=new t(e);try{n=new CustomEvent("LazyLoad::Initialized",{detail:{instance:o}})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent("LazyLoad::Initialized",!1,!1,{instance:o})}window.dispatchEvent(n)},g=function(t,e){return e?t.replace(/\.(jpe?g|png)/gi,".webp"):t},m="undefined"!=typeof window,w=m&&!("onscroll"in window)||/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),v=m&&"classList"in document.createElement("p"),b=m&&function(){var t=document.createElement("canvas");return!(!t.getContext||!t.getContext("2d"))&&0===t.toDataURL("image/webp").indexOf("data:image/webp")}(),y=function(t,e){v?t.classList.add(e):t.className+=(t.className?" ":"")+e},E=function(t,e){v?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\s+)"+e+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")},L=function(t,e,n,i){for(var s,r=0;s=t.children[r];r+=1)if("SOURCE"===s.tagName){var l=o(s,n);T(s,e,l,i)}},T=function(t,e,n,o){n&&t.setAttribute(e,g(n,o))},S=function(t,e){var n=b&&e.to_webp,i=o(t,e.data_src),s=o(t,e.data_bg);if(i){var r=g(i,n);t.style.backgroundImage='url("'+r+'")'}if(s){var l=g(s,n);t.style.backgroundImage=l}},O={IMG:function(t,e){var n=b&&e.to_webp,i=e.data_srcset,s=t.parentNode;s&&"PICTURE"===s.tagName&&L(s,"srcset",i,n);var r=o(t,e.data_sizes);T(t,"sizes",r);var l=o(t,i);T(t,"srcset",l,n);var a=o(t,e.data_src);T(t,"src",a,n)},IFRAME:function(t,e){var n=o(t,e.data_src);T(t,"src",n)},VIDEO:function(t,e){var n=e.data_src,i=o(t,n);L(t,"src",n),T(t,"src",i),t.load()}},H=function(t,e){var n=e._settings,o=t.tagName,i=O[o];if(i)return i(t,n),e._updateLoadingCount(1),void(e._elements=a(e._elements,t));S(t,n)},C=function(t,e){t&&t(e)},k=function(t,e,n){t.addEventListener(e,n)},z=function(t,e,n){t.removeEventListener(e,n)},N=function(t,e,n){k(t,"load",e),k(t,"loadeddata",e),k(t,"error",n)},A=function(t,e,n){z(t,"load",e),z(t,"loadeddata",e),z(t,"error",n)},I=function(t,e,n){var o=n._settings,i=e?o.class_loaded:o.class_error,s=e?o.callback_load:o.callback_error,r=t.target;E(r,o.class_loading),y(r,i),C(s,r),n._updateLoadingCount(-1)},x=function(t,e){var n=function n(i){I(i,!0,e),A(t,n,o)},o=function o(i){I(i,!1,e),A(t,n,o)};N(t,n,o)},R=["IMG","IFRAME","VIDEO"],D=function(t,e){for(;e.length;)t.splice(e.pop(),1)},F=function(t){this._settings=_extends({},n(),t),this._loadingCount=0,this._queryOriginNode=this._settings.container===window?document:this._settings.container,this._previousLoopTime=0,this._loopTimeout=null,this._boundHandleScroll=this.handleScroll.bind(this),this._isFirstLoop=!0,window.addEventListener("resize",this._boundHandleScroll),this.update()};return F.prototype={_loopThroughElements:function(e){var n=this._settings,o=this._elements,i=o?o.length:0,s=void 0,r=[],l=this._isFirstLoop;if(l&&(this._isFirstLoop=!1),0!==i){for(s=0;s<i;s++){var a=o[s];n.skip_invisible&&null===a.offsetParent||(e||t(a,n.container,n.threshold))&&(l&&y(a,n.class_initial),this.load(a),r.push(s))}D(o,r)}else this._stopScrollHandler()},_startScrollHandler:function(){this._isHandlingScroll||(this._isHandlingScroll=!0,this._settings.container.addEventListener("scroll",this._boundHandleScroll))},_stopScrollHandler:function(){this._isHandlingScroll&&(this._isHandlingScroll=!1,this._settings.container.removeEventListener("scroll",this._boundHandleScroll))},_updateLoadingCount:function(t){this._loadingCount+=t,0===this._elements.length&&0===this._loadingCount&&C(this._settings.callback_finish)},handleScroll:function(){var t=this._settings.throttle;if(0!==t){var e=Date.now(),n=t-(e-this._previousLoopTime);n<=0||n>t?(this._loopTimeout&&(clearTimeout(this._loopTimeout),this._loopTimeout=null),this._previousLoopTime=e,this._loopThroughElements()):this._loopTimeout||(this._loopTimeout=setTimeout(function(){this._previousLoopTime=Date.now(),this._loopTimeout=null,this._loopThroughElements()}.bind(this),n))}else this._loopThroughElements()},loadAll:function(){this._loopThroughElements(!0)},update:function(t){var e=this._settings,n=t||this._queryOriginNode.querySelectorAll(e.elements_selector);this._elements=l(Array.prototype.slice.call(n)),w?this.loadAll():(this._loopThroughElements(),this._startScrollHandler())},destroy:function(){window.removeEventListener("resize",this._boundHandleScroll),this._loopTimeout&&(clearTimeout(this._loopTimeout),this._loopTimeout=null),this._stopScrollHandler(),this._elements=null,this._queryOriginNode=null,this._settings=null},load:function(t,n){e(t,this,n)}},m&&function(t,e){if(e)if(e.length)for(var n,o=0;n=e[o];o+=1)p(t,n);else p(t,e)}(F,window.lazyLoadOptions),F});
//# sourceMappingURL=lazyload.min.js.map
.inline {
display: inline-block;
vertical-align: top;
text-align: center;
}
.twenty5 {
width: 20vw;
}
.fifty {
max-width: 30%;
}
#wsoutput {
min-width: 200px;
}
#exchange-container {
min-width: 200px;
max-width: 400px;
}
#exchanges {
max-height: 200px;
overflow-y: scroll;
}
.exchange-item {
cursor: pointer;
text-decoration: none;
}
.grid-container-4 {
display: grid;
grid-template-columns: auto auto auto auto;
background-color: #2196F3;
grid-gap: 10px;
padding: 5px;
}
.grid-container-2 {
display: grid;
grid-template-columns: auto auto;
background-color: #2196F3;
grid-gap: 10px;
padding: 5px;
}
.grid-item {
background-color: rgba(255, 255, 255, 0.8);
padding: 2px;
font-size: 10px;
text-align: center;
}
#wsoutput2 {
overflow-y: scroll;
max-height: 200px;
}
#container {
max-height: 600px;
overflow-y: scroll;
}
img:not([src]) {
visibility: hidden;
}
.hide {
display: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment