From a9b5a904d87d00f3f4fa98c5a756a9fa5c799383 Mon Sep 17 00:00:00 2001 From: michael1011 Date: Sun, 1 Apr 2018 15:51:40 +0200 Subject: [PATCH] improved generation of QR codes --- backends/lnd.go | 2 +- frontend/lightningTip.css | 6 ++- frontend/lightningTip.js | 87 +++++++++++++++++++++++---------------- lightningtip.go | 2 +- 4 files changed, 58 insertions(+), 39 deletions(-) diff --git a/backends/lnd.go b/backends/lnd.go index 2d1b127..d312817 100644 --- a/backends/lnd.go +++ b/backends/lnd.go @@ -130,4 +130,4 @@ func getMacaroon(macaroonFile string) (macaroon metadata.MD, err error) { } return macaroon, err -} \ No newline at end of file +} diff --git a/frontend/lightningTip.css b/frontend/lightningTip.css index 5df2181..00d956e 100644 --- a/frontend/lightningTip.css +++ b/frontend/lightningTip.css @@ -100,6 +100,10 @@ margin-bottom: 0.5em; } +#lightningTipQR { + margin-bottom: 0.8em; +} + #lightningTipTools { height: 100px; } @@ -121,7 +125,7 @@ } #lightningTipExpiry { - padding: 0.2em 0; + padding: 0.3em 0; float: right; } diff --git a/frontend/lightningTip.js b/frontend/lightningTip.js index 80f9001..049e648 100644 --- a/frontend/lightningTip.js +++ b/frontend/lightningTip.js @@ -10,6 +10,29 @@ var qrCode; var defaultGetInvoice; +// Data capacities for QR codes with mode byte and error correction level L (7%) +// Shortest invoice: 194 characters +// Longest invoice: 1223 characters (as far as I know) +var qrCodeDataCapacities = [ + {"typeNumber": 9, "capacity": 230}, + {"typeNumber": 10, "capacity": 271}, + {"typeNumber": 11, "capacity": 321}, + {"typeNumber": 12, "capacity": 367}, + {"typeNumber": 13, "capacity": 425}, + {"typeNumber": 14, "capacity": 458}, + {"typeNumber": 15, "capacity": 520}, + {"typeNumber": 16, "capacity": 586}, + {"typeNumber": 17, "capacity": 644}, + {"typeNumber": 18, "capacity": 718}, + {"typeNumber": 19, "capacity": 792}, + {"typeNumber": 20, "capacity": 858}, + {"typeNumber": 21, "capacity": 929}, + {"typeNumber": 22, "capacity": 1003}, + {"typeNumber": 23, "capacity": 1091}, + {"typeNumber": 24, "capacity": 1171}, + {"typeNumber": 25, "capacity": 1273} +]; + // TODO: solve this without JavaScript // Fixes weird bug which moved the button up one pixel when its content was changed window.onload = function () { @@ -19,6 +42,7 @@ window.onload = function () { button.style.width = (button.clientWidth + 1) + "px"; }; +// TODO: show invoice even if JavaScript is disabled // TODO: fix scaling on phones // TODO: optimize creating bigger QR codes // TODO: show price in dollar? @@ -62,8 +86,6 @@ function getInvoice() { resizeInput(document.getElementById("lightningTipInvoice")); - showQRCode(); - wrapper.innerHTML += "
" + "" + "" + @@ -79,6 +101,8 @@ function getInvoice() { location.href = "lightning:" + json.Invoice; }; + showQRCode(); + running = false; } else { @@ -222,53 +246,43 @@ function addLeadingZeros(value) { function showQRCode() { var element = document.getElementById("lightningTipQR"); - if (!element.hasChildNodes()) { - // Show the QR code - console.log("Showing QR code"); + createQRCode(); - // QR code was not shown yet - if (qrCode == null) { - createQRCode(10); - } + element.innerHTML = qrCode; - element.style.marginBottom = "0.8em"; - element.innerHTML = qrCode; + var size = document.getElementById("lightningTipInvoice").clientWidth + "px"; - var size = document.getElementById("lightningTipInvoice").clientWidth + "px"; - - var qrElement = element.children[0]; - - qrElement.style.height = size; - qrElement.style.width = size; - - } else { - // Hide the QR code - console.log("Hiding QR code"); - - element.style.marginBottom = "0"; - element.innerHTML = ""; - - } + var qrElement = element.children[0]; + qrElement.style.height = size; + qrElement.style.width = size; } -function createQRCode(typeNumber) { - try { - console.log("Creating QR code with type number: " + typeNumber); +function createQRCode() { + var invoiceLength = invoice.length; - var qr = qrcode(typeNumber, "L"); + // Just in case an invoice bigger than expected gets created + var typeNumber = 26; - qr.addData(invoice); - qr.make(); + for (var i = 0; i < qrCodeDataCapacities.length; i++) { + var dataCapacity = qrCodeDataCapacities[i]; - qrCode = qr.createImgTag(6, 6); + if (invoiceLength < dataCapacity.capacity) { + typeNumber = dataCapacity.typeNumber; - } catch (e) { - console.log("Overflow error. Trying bigger type number"); + break; + } - createQRCode(typeNumber + 1); } + console.log("Creating QR code with type number: " + typeNumber); + + var qr = qrcode(typeNumber, "L"); + + qr.addData(invoice); + qr.make(); + + qrCode = qr.createImgTag(6, 6); } function copyInvoiceToClipboard() { @@ -300,6 +314,7 @@ function showErrorMessage(message) { } +// TODO: better way scaling function resizeInput(element) { element.style.height = "auto"; diff --git a/lightningtip.go b/lightningtip.go index 086a45f..f6436e6 100644 --- a/lightningtip.go +++ b/lightningtip.go @@ -54,7 +54,6 @@ type errorResponse struct { Error string } -// TODO: add setup guide for systemd // TODO: add option to show URI of Lightning node func main() { initLog() @@ -214,6 +213,7 @@ func getInvoiceHandler(writer http.ResponseWriter, request *http.Request) { if body.Amount != 0 { invoice, err := backend.GetInvoice(body.Message, body.Amount, cfg.TipExpiry) + // TODO: handle too long messages better if err == nil { logMessage := "Created invoice with amount of " + strconv.FormatInt(body.Amount, 10) + " satoshis"