From 7762ceaa7e2bb34f8758e17a4c8f512fa6a81b9e Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sun, 15 Jan 2017 18:24:09 -0800 Subject: Initial Vueification --- static/js/calculator.coffee | 268 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 static/js/calculator.coffee (limited to 'static/js/calculator.coffee') diff --git a/static/js/calculator.coffee b/static/js/calculator.coffee new file mode 100644 index 00000000..75192596 --- /dev/null +++ b/static/js/calculator.coffee @@ -0,0 +1,268 @@ +EXCHANGE_FAIL = "Problem fetching exchange rate" +SOCKET_FAIL = "Problem connecting to payment server, notifications may not appear" +ADDRESS_FAIL = "Invalid address" +API_URL = "wss://socket.blockcypher.com/v1/btc/main" +TEST_URL = "wss://socket.blockcypher.com/v1/btc/test3" + +g = exports ? this +g.errors = [] +g.amount_requested = 0 +g.amount = 0.toFixed(2) +g.tip = 1 +g.transactions = [] + +$(-> + $.ajax( + url: $('#user').val() + '.json', + dataType: 'json', + success: (data) -> + g.user = data + setup() + ) + + $('button').click((e) -> + e.preventDefault() + ) + + $('.numpad .btn').off('click').click((e) -> + e.preventDefault() + + m = $(this).html() + n = parseFloat($('.amount').html()) + + if m is 'C' + g.amount = 0.toFixed(2) + updateTotal() + return + + return if n > 10000000 + + if m is '00' + n = 100 * n + else + n = 10 * n + parseFloat(m) / 100 + + g.amount = n.toFixed(2) + + updateTotal() + ) + + $('.numpad .btn:last').off('click').click((e) -> + e.preventDefault() + + g.amount = (Math.floor(100 * (parseFloat($('.amount').html()) / 10)) / 100).toFixed(2) + updateTotal() + ) + + $('.tippad .btn').off('click').click((e) -> + e.preventDefault() + + text = $(this).html() + if text is 'No Tip' + value = 0 + else + value = text.slice(1, -1) + + $(this).addClass('active') + $(this).siblings().removeClass('active') + g.tip = 1 + (parseFloat(value)/100) + updateTotal() + ) + + $('#received').click(-> window.location = "/#{g.user.username}/report") + $('#slide').click(-> + $('#controls').slideToggle() + $(this).find('i').toggleClass('fa-sort-up').toggleClass('fa-sort-down') + ) +) + +setup = -> + g.user.address or= '' + g.user.commission or= 0 + g.user.currency or= 'CAD' + g.user.symbol or= 'quadrigacx' + g.user.unit or= 'BTC' + + if g.user.title + $('#title').html("#{g.user.title}").show() + + if g.user.logo + ext = g.user.logo.substr(g.user.logo.length - 3) + src = "/img/logos/#{g.user.username}.#{ext}" + $('#logo').attr('src', src).show() + + getAddress() + if g.user.address[0] is 'm' + API_URL = TEST_URL + + $('.symbol').html(g.user.currency) + $('.currency').html(g.user.currency) + $('.unit').html(g.user.unit) + + $('#received').hide() + + fetchExchangeRate() + listen() + +fetchExchangeRate = -> + $.ajax( + url: "ticker?currency=#{g.user.currency}&symbol=#{g.user.symbol}&type=bid", + success: (exchange) -> + if exchange? + clear(EXCHANGE_FAIL) + else + fail(EXCHANGE_FAIL) + return + + g.exchange = (exchange - exchange * g.user.commission * 0.01).toFixed(2) + $('#exchange').html(g.exchange) + updateTotal() + + unless g.setupComplete + g.setupComplete = true + + error: -> fail(EXCHANGE_FAIL) + ) + setTimeout(fetchExchangeRate, 900000) + +updateTotal = -> + precision = 9 - multiplier().toString().length + subtotal = parseFloat(g.amount * g.tip).toFixed(2) + total = (subtotal * multiplier() / g.exchange).toFixed(precision) + g.amount_requested = (subtotal / g.exchange).toFixed(8) + + unless $.isNumeric(total) + total = '' + + $('#received').hide() + $('#payment').fadeIn('slow') + + $('.tip').html((subtotal - g.amount).toFixed(2)) + $('.subtotal').html(subtotal.toString()) + $('.amount').html(g.amount) + $('.exchange').html(g.exchange) + $('.symbol').html(g.user.symbol) + + if g.user.commission < 0 + $('.commission').html("+#{Math.abs(g.user.commission)}%") + + + $('#total').html(total.toString()) + + size = 300 + $('#qr').css('height', size) + + time = 0 + if g.timeout + time = 10 + + clearTimeout(g.timeout) + g.timeout = setTimeout(-> + $('#qr').html('') + new QRCode('qr', + text: "bitcoin:#{g.user.address}?amount=#{g.amount_requested.toString()}" + width: size + height: size + ) + , time) + +listen = -> + g.attempts++ + if g.blockchain and g.blockchain.readyState is 1 + setTimeout(listen, 12000) + else + fail(SOCKET_FAIL) if g.attempts > 3 + g.blockchain = new WebSocket(API_URL) + + g.blockchain.onopen = -> + if g.blockchain.readyState is 1 + g.attempts = 0 + clear(SOCKET_FAIL) + g.blockchain.send('{"event":"unconfirmed-tx", "address":"' + g.user.address + '"}') + else + setTimeout(g.blockchain.onopen, 12000 * g.attempts) + + g.blockchain.onerror = -> + fail(SOCKET_FAIL) + g.blockchain.close() + delete g.blockchain + listen() + + g.blockchain.onclose = -> + delete g.blockchain + listen() + + g.blockchain.onmessage = (e) -> + tx = JSON.parse(e.data) + amount = 0 + + return if tx.hash == g.last_seen + g.last_seen = tx.hash + + for output in tx.outputs + if (output.addresses[0] == g.user.address) + amount += output.value / 100000000 + + logTransaction(tx.hash, amount) + +logTransaction = (txid, amount) -> + if $('#received').is(":hidden") and amount >= g.amount_requested + $('#payment').hide() + $('#received').fadeIn('slow') + $('#success')[0].play() + g.user.index++ + + if g.transactions.indexOf(txid) is -1 + g.transactions.push(txid) + $.post("/#{g.user.username}/transactions", + txid: txid, + address: g.user.address, + date: moment().format("YYYY-MM-DD HH:mm:ss"), + received: amount, + exchange: g.exchange + tip: g.tip + ) + + getAddress() + +getAddress = -> + try + bitcoin.address.fromBase58Check(g.user.pubkey) + g.user.address = g.user.pubkey + catch + master = bitcoin.HDNode.fromBase58(g.user.pubkey) + child = master.derive(0).derive(g.user.index) + g.user.address = child.getAddress().toString() + g.blockchain.close() if g.blockchain + listen() + + $('#address').html("#{g.user.address}") + +fail = (msg) -> + g.errors.push(msg) + g.errors = g.errors.uniq() + $('#error').show().html(g.errors.toString()) + +clear = (msg) -> + i = g.errors.indexOf(msg) + g.errors.splice(i, 1) if i >= 0 + if (g.errors.length > 0) + $('#error').show().html(g.errors.toString()) + else + $('#error').hide() + $('#calculator').fadeIn('slow') + +Array::uniq = -> + output = {} + output[@[key]] = @[key] for key in [0...@length] + value for key, value of output + +multiplier = -> + switch g.user.unit + when 'BTC' then 1 + when 'mBTC' then 1000 + when 'µBTC' then 1000000 + when 'bits' then 1000000 + when 'satoshis' then 100000000 + + -- cgit v1.2.3