diff --git a/app.js b/app.js deleted file mode 100644 index 4ce8b10..0000000 --- a/app.js +++ /dev/null @@ -1,188 +0,0 @@ -(function() { - 'use strict'; - - var socket = io("https://insight.dash.org:443/"); - var transactionList = document.getElementById('transactionList'); - var muteButton = document.getElementById('muteToggle'); - var muted = false; - var audioContext; - var audioGainNode; - var backgroundSound; - var soundBuffers = { - 'tx': null, - 'block': null - }; - var domRefList = []; - window.addEventListener('load', init, false); - - function init() { - if (localStorage) { - muted = localStorage.getItem('muted'); - if (muted === null) { - muted = false; - localStorage.setItem('muted', muted); - } else { - muted = (muted == 'true'); // localStorage stores strings not objects? - } - muteButton.className = (muted === true ? 'is-muted' : ''); - } - - muteButton.onclick = toggleMute; - - try { - window.AudioContext = window.AudioContext||window.webkitAudioContext; - audioContext = new AudioContext(); - audioGainNode = audioContext.createGain(); - audioGainNode.connect(audioContext.destination); - audioGainNode.gain.value = 0.6; - } - catch(e) { - console.error('Unable to use Web Audio API'); - document.getElementById('muteToggle').remove(); - } - try { - loadSound('assets/whoosh.mp3', 'block'); - loadSound('assets/bell.mp3', 'tx-sm'); - loadSound('assets/wood-hit-glass.mp3', 'tx-md'); - loadSound('assets/metallophone.mp3', 'tx-lg'); - loadSound('assets/creek.mp3', 'background', function() { - backgroundSound = audioContext.createBufferSource(); - backgroundSound.buffer = soundBuffers['background']; - backgroundSound.connect(audioGainNode); - backgroundSound.loop = true; - if (!muted) { - backgroundSound.start(); - } - }); - } - catch(e) { - console.error('Couldn\'t load sounds.'); - } - - socket.on('connect', function() { - document.getElementById('connectionStatus').className = 'is-connected'; - // Join the room. - socket.emit('subscribe', 'inv'); - }) - socket.on('tx', onTransaction); - socket.on('block', onBlock); - socket.on('disconnect', function() { - document.getElementById('connectionStatus').className = 'is-disconnected'; - }); - socket.on('reconnecting', function() { - document.getElementById('connectionStatus').className = 'is-connecting'; - }); - } - - function loadSound(url, bufferName, callback) { - var request = new XMLHttpRequest(); - request.open('GET', url, true); - request.responseType = 'arraybuffer'; - - // Decode asynchronously - request.onload = function() { - audioContext.decodeAudioData(request.response, function(buffer) { - soundBuffers[bufferName] = buffer; - if (callback) { - callback(); - } - }); - console.log('Loaded ' + url + ' as "' + bufferName + '"'); - } - request.send(); - } - - function playSound(bufferName, playbackRate) { - if (muted === true) { - return; - } - var source = audioContext.createBufferSource(); - source.buffer = soundBuffers[bufferName]; - source.connect(audioGainNode); - source.playbackRate.value = playbackRate; - source.start(); - } - - function playbackRate(value, vMin, vMax, oMin, oMax) { - return Math.min(Math.max(oMin, - (Math.log(value) - Math.log(vMin)) / (Math.log(vMax) - Math.log(vMin)) * (oMin - oMax) + oMax - ), oMax); - } - - var toggleMute = function() { - muted = !muted; - if (localStorage) { - localStorage.setItem('muted', muted); - } - muteButton.className = (muted === true ? 'is-muted' : ''); - if (muted) { - backgroundSound.stop(); - } else { - backgroundSound = audioContext.createBufferSource(); - backgroundSound.buffer = soundBuffers['background']; - backgroundSound.connect(audioGainNode); - backgroundSound.loop = true; - backgroundSound.start(); - } - } - - var onTransaction = function(data) { - console.log(data); - if (!muted) { - if (data.valueOut < 10) { - playSound('tx-sm', playbackRate(data.valueOut, 0.00001, 10, 1, 1.5)); - } else if (data.valueOut < 1000) { - playSound('tx-md', playbackRate(data.valueOut, 10, 1000, 0.5, 1)); - } else if (data.valueOut >= 1000) { - playSound('tx-lg', playbackRate(data.valueOut, 6000, 1000, 0.25, 1)); - } - } - var tx = document.createElement('div'); - tx.className = 'tx'; - var txValue = document.createElement('a'); - txValue.className = 'txValue'; - txValue.href = 'https://blockchain.masternode.io/tx/' + data.txid; - txValue.target = '_blank'; - txValue.setAttribute('rel', 'noopener'); - var txOutputs = document.createElement('div'); - txOutputs.className = 'txOutputs'; - txOutputs.style.height = (data.valueOut / 10 + 0.1) + 'em' - txValue.appendChild(document.createTextNode(data.valueOut)); - tx.appendChild(txValue); - tx.appendChild(txOutputs); - var transactions = data.vout; -// var transactions = data.vout.sort(function(a, b) { // sort descending by tx value -// return b[Object.keys(b)[0]] - a[Object.keys(a)[0]]; -// }); - transactions.forEach(function(value, index, array) { - var txOut = document.createElement('div'); - var outputSatoshis = value[Object.keys(value)[0]]; - txOut.className = 'txOut'; - txOut.style.width = (outputSatoshis * 0.00001).toFixed(4) + 'px'; - txOut.title = (value[Object.keys(value)[0]] * 0.00000001); - txOutputs.appendChild(txOut); - }); - if (domRefList.unshift(tx) > 300) { - var toDelete = domRefList.pop(); - toDelete.remove(); - } - transactionList.insertBefore(tx, transactionList.firstChild); - }; - - var onBlock = function(data) { - console.log(data); - playSound('block', 1); - var newBlock = document.createElement('a'); - newBlock.className = 'blockDivider'; - newBlock.href = 'https://blockchain.masternode.io/block/' + data; - newBlock.target = '_blank'; - newBlock.setAttribute('rel', 'noopener'); - newBlock.appendChild(document.createTextNode(data)); - if (domRefList.unshift(newBlock) > 300) { - var toDelete = domRefList.pop(); - toDelete.remove(); - } - transactionList.insertBefore(newBlock, transactionList.firstChild); - }; - -})(); diff --git a/dist/bundle.js b/dist/bundle.js new file mode 100644 index 0000000..fbe6b33 --- /dev/null +++ b/dist/bundle.js @@ -0,0 +1,280 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_js_run_js__ = __webpack_require__(1); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_js_run_js___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_js_run_js__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_main_less__ = __webpack_require__(2); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_main_less___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_main_less__); + + + + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var socket = io("https://insight.dash.org:443/"); +var transactionList = document.getElementById('transactionList'); +var muteButton = document.getElementById('muteToggle'); +var muted = false; +var audioContext; +var audioGainNode; +var backgroundSound; +var soundBuffers = { + 'tx': null, + 'block': null +}; +var domRefList = []; +window.addEventListener('load', init, false); + +function init() { + if (localStorage) { + muted = localStorage.getItem('muted'); + if (muted === null) { + muted = false; + localStorage.setItem('muted', muted); + } else { + muted = (muted == 'true'); // localStorage stores strings not objects? + } + muteButton.className = (muted === true ? 'is-muted' : ''); + } + + muteButton.onclick = toggleMute; + + try { + window.AudioContext = window.AudioContext||window.webkitAudioContext; + audioContext = new AudioContext(); + audioGainNode = audioContext.createGain(); + audioGainNode.connect(audioContext.destination); + audioGainNode.gain.value = 0.6; + } + catch(e) { + console.error('Unable to use Web Audio API'); + document.getElementById('muteToggle').remove(); + } + try { + loadSound('assets/whoosh.mp3', 'block'); + loadSound('assets/bell.mp3', 'tx-sm'); + loadSound('assets/wood-hit-glass.mp3', 'tx-md'); + loadSound('assets/metallophone.mp3', 'tx-lg'); + loadSound('assets/creek.mp3', 'background', function() { + backgroundSound = audioContext.createBufferSource(); + backgroundSound.buffer = soundBuffers['background']; + backgroundSound.connect(audioGainNode); + backgroundSound.loop = true; + if (!muted) { + backgroundSound.start(); + } + }); + } + catch(e) { + console.error('Couldn\'t load sounds.'); + } + + socket.on('connect', function() { + document.getElementById('connectionStatus').className = 'is-connected'; + // Join the room. + socket.emit('subscribe', 'inv'); + }) + socket.on('tx', onTransaction); + socket.on('block', onBlock); + socket.on('disconnect', function() { + document.getElementById('connectionStatus').className = 'is-disconnected'; + }); + socket.on('reconnecting', function() { + document.getElementById('connectionStatus').className = 'is-connecting'; + }); +} + +function loadSound(url, bufferName, callback) { + var request = new XMLHttpRequest(); + request.open('GET', url, true); + request.responseType = 'arraybuffer'; + + // Decode asynchronously + request.onload = function() { + audioContext.decodeAudioData(request.response, function(buffer) { + soundBuffers[bufferName] = buffer; + if (callback) { + callback(); + } + }); + console.log('Loaded ' + url + ' as "' + bufferName + '"'); + } + request.send(); +} + +function playSound(bufferName, playbackRate) { + if (muted === true) { + return; + } + var source = audioContext.createBufferSource(); + source.buffer = soundBuffers[bufferName]; + source.connect(audioGainNode); + source.playbackRate.value = playbackRate; + source.start(); +} + +function playbackRate(value, vMin, vMax, oMin, oMax) { + return Math.min(Math.max(oMin, + (Math.log(value) - Math.log(vMin)) / (Math.log(vMax) - Math.log(vMin)) * (oMin - oMax) + oMax + ), oMax); +} + +var toggleMute = function() { + muted = !muted; + if (localStorage) { + localStorage.setItem('muted', muted); + } + muteButton.className = (muted === true ? 'is-muted' : ''); + if (muted) { + backgroundSound.stop(); + } else { + backgroundSound = audioContext.createBufferSource(); + backgroundSound.buffer = soundBuffers['background']; + backgroundSound.connect(audioGainNode); + backgroundSound.loop = true; + backgroundSound.start(); + } +} + +var onTransaction = function(data) { + console.log(data); + if (!muted) { + if (data.valueOut < 10) { + playSound('tx-sm', playbackRate(data.valueOut, 0.00001, 10, 1, 1.5)); + } else if (data.valueOut < 1000) { + playSound('tx-md', playbackRate(data.valueOut, 10, 1000, 0.5, 1)); + } else if (data.valueOut >= 1000) { + playSound('tx-lg', playbackRate(data.valueOut, 6000, 1000, 0.25, 1)); + } + } + var tx = document.createElement('div'); + tx.className = 'tx'; + var txValue = document.createElement('a'); + txValue.className = 'txValue'; + txValue.href = 'https://blockchain.masternode.io/tx/' + data.txid; + txValue.target = '_blank'; + txValue.setAttribute('rel', 'noopener'); + var txOutputs = document.createElement('div'); + txOutputs.className = 'txOutputs'; + txOutputs.style.height = (data.valueOut / 10 + 0.1) + 'em' + txValue.appendChild(document.createTextNode(data.valueOut)); + tx.appendChild(txValue); + tx.appendChild(txOutputs); + var transactions = data.vout; +// var transactions = data.vout.sort(function(a, b) { // sort descending by tx value +// return b[Object.keys(b)[0]] - a[Object.keys(a)[0]]; +// }); + transactions.forEach(function(value, index, array) { + var txOut = document.createElement('div'); + var outputSatoshis = value[Object.keys(value)[0]]; + txOut.className = 'txOut'; + txOut.style.width = (outputSatoshis * 0.00001).toFixed(4) + 'px'; + txOut.title = (value[Object.keys(value)[0]] * 0.00000001); + txOutputs.appendChild(txOut); + }); + if (domRefList.unshift(tx) > 300) { + var toDelete = domRefList.pop(); + toDelete.remove(); + } + transactionList.insertBefore(tx, transactionList.firstChild); +}; + +var onBlock = function(data) { + console.log(data); + playSound('block', 1); + var newBlock = document.createElement('a'); + newBlock.className = 'blockDivider'; + newBlock.href = 'https://blockchain.masternode.io/block/' + data; + newBlock.target = '_blank'; + newBlock.setAttribute('rel', 'noopener'); + newBlock.appendChild(document.createTextNode(data)); + if (domRefList.unshift(newBlock) > 300) { + var toDelete = domRefList.pop(); + toDelete.remove(); + } + transactionList.insertBefore(newBlock, transactionList.firstChild); +}; + + + +/***/ }), +/* 2 */ +/***/ (function(module, exports) { + +// removed by extract-text-webpack-plugin + +/***/ }) +/******/ ]); \ No newline at end of file diff --git a/dist/style.css b/dist/style.css new file mode 100644 index 0000000..b72fad7 --- /dev/null +++ b/dist/style.css @@ -0,0 +1,195 @@ +body { + padding: 0; + margin: 0; + -webkit-box-sizing: border-box; + box-sizing: border-box; + font-family: sans-serif; + font-size: 140%; + background-image: url(assets/Dash-logo.svg), -webkit-gradient(linear, left top, right bottom, from(#1e73be), to(#073a66)); + background-image: url(assets/Dash-logo.svg), -o-linear-gradient(top left, #1e73be, #073a66); + background-image: url(assets/Dash-logo.svg), linear-gradient(to bottom right, #1e73be, #073a66); + background-size: 50vmin auto, cover; + background-position: center; + background-attachment: fixed; + background-repeat: no-repeat; + background-color: #1e73be; + color: white; + min-height: 100vh; +} +* { + -webkit-box-sizing: inherit; + box-sizing: inherit; +} +a { + color: inherit; + text-decoration: none; +} +#transactionList { + padding: 1em 0 0; + mix-blend-mode: screen; + opacity: 0.75; + height: 100vh; + overflow: hidden; +} +#transactionList:after { + content: ''; + position: fixed; + bottom: 0; + height: 8em; + left: 0; + right: 0; + background-image: -webkit-gradient(linear, left bottom, left top, from(black), to(transparent)); + background-image: -o-linear-gradient(bottom, black, transparent); + background-image: linear-gradient(to top, black, transparent); + z-index: 2; + pointer-events: none; +} +#connectionStatus.is-connected ~ #transactionList:empty:before { + content: 'Waiting for first transaction...'; + display: block; + text-align: center; + font-size: 2em; + opacity: 0.5; +} +.tx { + position: relative; + margin: 3px auto; + width: 20em; + min-width: 80%; + max-width: 100%; + z-index: 1; +} +.txValue { + display: none; + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + line-height: 1.25; +} +.txOutputs { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + -ms-flex-line-pack: stretch; + align-content: stretch; +} +.txOut { + position: relative; + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + background-color: white; +} +.txOut:first { + border-left: 3px solid black; +} +.txOut:after { + content: ''; + width: 3px; + background: black; + position: absolute; + right: 0; + top: 0; + bottom: 0; +} +.blockDivider { + display: block; + margin: 1em -1em -1.5em; + background: -webkit-gradient(linear, left bottom, left top, from(rgba(255, 255, 255, 0)), to(rgba(255, 255, 255, 0.125))); + background: -o-linear-gradient(bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.125)); + background: linear-gradient(to top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.125)); + padding: 0.125em 1em 1.5em; + color: rgba(0, 0, 0, 0); + text-align: center; + white-space: nowrap; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; +} +.blockDivider:hover, +.blockDivider:focus { + color: inherit; +} +#muteToggle, +#connectionStatus { + position: fixed; + top: 0; + width: 8em; + background: white; + border: solid black; + padding: 0.5em; + font-size: 0.8em; + text-transform: uppercase; + font-weight: bold; + text-align: center; + color: black; +} +#muteToggle { + left: 0; + border-radius: 0 0 0.5em 0; + border-width: 0 0.1em 0.1em 0; + -webkit-transition: opacity 0.5s; + -o-transition: opacity 0.5s; + transition: opacity 0.5s; + -webkit-transition-delay: 1s; + -o-transition-delay: 1s; + transition-delay: 1s; + opacity: 0; + cursor: pointer; + z-index: 100; +} +#muteToggle:hover { + opacity: 1; + -webkit-transition-delay: 0s; + -o-transition-delay: 0s; + transition-delay: 0s; +} +#muteToggle:before { + content: 'Mute'; +} +#muteToggle.is-muted:before { + content: 'Un-mute'; +} +#connectionStatus { + right: 0; + border-radius: 0 0 0 0.5em; + border-width: 0 0 0.1em 0.1em; + -webkit-transition: -webkit-transform 0.5s; + transition: -webkit-transform 0.5s; + -o-transition: transform 0.5s; + transition: transform 0.5s; + transition: transform 0.5s, -webkit-transform 0.5s; + -webkit-transform: none; + -ms-transform: none; + transform: none; +} +#connectionStatus.is-disconnected:before { + content: 'Disconnected'; + color: red; +} +#connectionStatus.is-connecting:before { + content: 'Connecting...'; + color: black; +} +#connectionStatus.is-connected:before { + content: 'Connected'; + color: green; +} +#connectionStatus.is-connected { + -webkit-transition: -webkit-transform 0.5s; + transition: -webkit-transform 0.5s; + -o-transition: transform 0.5s; + transition: transform 0.5s; + transition: transform 0.5s, -webkit-transform 0.5s; + -webkit-transition-delay: 2s; + -o-transition-delay: 2s; + transition-delay: 2s; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); +} diff --git a/index.html b/index.html index 462397f..caed2b8 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@