diff --git a/frontend/lightningTip.css b/frontend/lightningTip.css index 0c2e184..60f6594 100644 --- a/frontend/lightningTip.css +++ b/frontend/lightningTip.css @@ -1,3 +1,41 @@ +.lightningTipInput { + width: 100%; + + display: inline-block; + + padding: 6px 10px; + + border: none; + border-radius: 4px; + + font-size: 15px; + + color: #212121; + + background-color: #F5F5F5; + + outline: none; + resize: none; + + overflow-y: hidden; +} + +.lightningTipButton { + padding: 0.4em 1em; + + font-size: 17px; + + color: #212121; + + background-color: #FFC83D; + + border: none; + border-radius: 4px; + + outline: none; + cursor: pointer; +} + #lightningTip { width: 12em; @@ -36,45 +74,8 @@ padding: 8px 10px; } -.lightningTipInput { - width: 100%; - - display: inline-block; - - padding: 6px 10px; - - border: none; - border-radius: 4px; - - font-size: 15px; - - color: #212121; - - background-color: #F5F5F5; - - outline: none; - resize: none; - - overflow-y: hidden; -} - #lightningTipGetInvoice { margin-top: 1em; - margin-bottom: 0.3em; - - padding: 0.4em 1em; - - font-size: 17px; - - color: #212121; - - background-color: #FFC83D; - - border: none; - border-radius: 4px; - - outline: none; - cursor: pointer; } #lightningTipError { @@ -84,7 +85,34 @@ } #lightningTipInvoice { - margin-top: 0.8em; + margin-top: 0.6em; + margin-bottom: 1em; +} + +#lightningTipTools { + height: 100px; +} + +#lightningTipGetQR { + border-right: 1px solid #F5F5F5; + + border-top-right-radius: 0; + border-bottom-right-radius: 0; + + float: left; +} + +#lightningTipOpen { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + + float: left; +} + +#lightningTipExpiry { + padding: 0.2em 0; + + float: right; } .spinner { diff --git a/frontend/lightningTip.html b/frontend/lightningTip.html index dfbdf86..dd00806 100644 --- a/frontend/lightningTip.html +++ b/frontend/lightningTip.html @@ -3,9 +3,8 @@ - - - + +
@@ -13,11 +12,11 @@ Send a tip via Lightning
- +
- +
diff --git a/frontend/lightningTip.js b/frontend/lightningTip.js index 26a1991..da4ac4b 100644 --- a/frontend/lightningTip.js +++ b/frontend/lightningTip.js @@ -3,67 +3,190 @@ function resizeInput(element) { element.style.height = (element.scrollHeight) + "px"; } +// To prohibit multiple requests at the same time +var running = false; +var invoice; +var qrCode; + +var defaultGetInvoice; + +// TODO: listen to eventsource and show tank you when invoice settled function getInvoice() { - var tipValue = document.getElementById("lightningTipAmount"); + if (running === false) { + running = true; - if (tipValue.value !== "") { - if (!isNaN(tipValue.value)) { - var data = JSON.stringify({"Amount": parseInt(tipValue.value), "Message": document.getElementById("lightningTipMessage").value}); + var tipValue = document.getElementById("lightningTipAmount"); - var request = new XMLHttpRequest(); + if (tipValue.value !== "") { - request.onreadystatechange = function () { - if (request.readyState === 4) { - var json = JSON.parse(request.responseText); + if (!isNaN(tipValue.value)) { + var data = JSON.stringify({"Amount": parseInt(tipValue.value), "Message": document.getElementById("lightningTipMessage").value}); - if (request.status === 200) { - console.log("Got invoice: " + json.Invoice); - console.log("Invoice expires in: " + json.Expiry); + var request = new XMLHttpRequest(); - var wrapper = document.getElementById("lightningTip"); + request.onreadystatechange = function () { + if (request.readyState === 4) { + try { + var json = JSON.parse(request.responseText); - // TODO: timer until expiry - wrapper.innerHTML = "Your invoice"; - wrapper.innerHTML += ""; + if (request.status === 200) { + console.log("Got invoice: " + json.Invoice); + console.log("Invoice expires in: " + json.Expiry); - resizeInput(document.getElementById("lightningTipInvoice")) + invoice = json.Invoice; + + var wrapper = document.getElementById("lightningTip"); + + wrapper.innerHTML = "Your invoice"; + wrapper.innerHTML += ""; + wrapper.innerHTML += "
"; + + resizeInput(document.getElementById("lightningTipInvoice")); + + wrapper.innerHTML += "
" + + "" + + "" + + "" + + "
"; + + starTimer(json.Expiry, document.getElementById("lightningTipExpiry")); + + document.getElementById("lightningTipTools").style.height = document.getElementById("lightningTipGetQR").clientHeight + "px"; + + document.getElementById("lightningTipOpen").onclick = function () { + location.href = "lightning:" + json.Invoice; + }; + + running = false; + + } else { + showErrorMessage(json.Error); + } + + } catch (exception) { + showErrorMessage("Failed to reach backend"); + } - } else { - showErrorMessage(json.Error); } - } + }; - }; + // TODO: proper url handling window.location.protocol + window.location.hostname + ":8081/getinvoice" + request.open("POST", "http://localhost:8081/getinvoice", true); + request.send(data); - // TODO: proper url handling window.location.protocol + window.location.hostname + ":8081/getinvoice" - request.open("POST", "http://localhost:8081/getinvoice", true); - request.send(data); + var button = document.getElementById("lightningTipGetInvoice"); - var button = document.getElementById("lightningTipGetInvoice"); + button.style.height = button.clientHeight + "px"; + button.style.width = button.clientWidth + "px"; - button.style.height = button.clientHeight + "px"; - button.style.width = button.clientWidth + "px"; + defaultGetInvoice = button.innerHTML; - button.innerHTML = "
"; + button.innerHTML = "
"; + + } else { + showErrorMessage("Tip amount must be a number"); + } } else { - showErrorMessage("Tip amount must be a number"); + showErrorMessage("No tip amount set"); } } else { - showErrorMessage("No tip amount set"); + console.warn("Last request still pending"); } } +function starTimer(duration, element) { + showTimer(duration, element); + + var interval = setInterval(function () { + if (duration > 0) { + duration--; + + showTimer(duration, element); + + } else { + clearInterval(interval); + } + + }, 1000); +} + +function showTimer(duration, element) { + var seconds = Math.floor(duration % 60); + var minutes = Math.floor((duration / 60) % 60); + var hours = Math.floor((duration / (60 * 60)) % 24); + + seconds = addLeadingZeros(seconds); + minutes = addLeadingZeros(minutes); + + if (hours > 0) { + element.innerHTML = hours + ":" + minutes + ":" + seconds; + + } else { + element.innerHTML = minutes + ":" + seconds; + } +} + +function addLeadingZeros(value) { + return ("0" + value).slice(-2); +} + +function showQRCode() { + var element = document.getElementById("lightningTipQR"); + + if (!element.hasChildNodes()) { + // Show the QR code + console.log("Showing QR code"); + + // QR code was not shown yet + if (qrCode == null) { + console.log("Creating QR code"); + + var size = document.getElementById("lightningTipInvoice").clientWidth; + + var qr = qrcode(10, "L"); + + qr.addData(invoice); + qr.make(); + + qrCode = qr.createImgTag(size / 60, 6); + } + + element.style.marginBottom = "1em"; + element.innerHTML = qrCode; + + } else { + // Hide the QR code + console.log("Hiding QR code"); + + element.style.marginBottom = "0"; + element.innerHTML = ""; + + } + +} + +function copyToClipboard(element) { + element.select(); + + document.execCommand('copy'); + + console.log("Copied invoice to clipboard"); +} + function showErrorMessage(message) { + running = false; + console.error(message); var error = document.getElementById("lightningTipError"); error.parentElement.style.marginTop = "0.5em"; - error.innerHTML = message; + + document.getElementById("lightningTipGetInvoice").innerHTML = defaultGetInvoice; } \ No newline at end of file