From d0ba5c6f30261915602e0004d50b04933c627c85 Mon Sep 17 00:00:00 2001 From: Lee Salminen Date: Mon, 4 Jul 2022 11:01:08 -0600 Subject: [PATCH 1/8] Improved support for Progressive Web Apps (PWA) - modify webmanifest to use LNBITS_SITE_TITLE and LNBITS_CUSTOM_LOGO env vars - modify webmanifest to have a more accurate description, start_url and set theme_color to match default lnbits theme - add service worker to cache requests (chrome requires a registered service worker to activate some pwa functionality) - move webmanifest to (chrome acts weird with it in the body) --- lnbits/core/static/js/service-worker.js | 71 +++++++++++++++++++++++++ lnbits/core/static/js/wallet.js | 7 +++ lnbits/core/templates/core/wallet.html | 2 +- lnbits/core/views/generic.py | 19 ++++--- 4 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 lnbits/core/static/js/service-worker.js diff --git a/lnbits/core/static/js/service-worker.js b/lnbits/core/static/js/service-worker.js new file mode 100644 index 000000000..3ff181948 --- /dev/null +++ b/lnbits/core/static/js/service-worker.js @@ -0,0 +1,71 @@ +// the cache version gets updated every time there is a new deployment +const CACHE_VERSION = 1; +const CURRENT_CACHE = `lnbits-${CACHE_VERSION}`; + +// these are the routes we are going to cache for offline support +const cacheFiles = [ + '/core/static/js/wallet.js', + '/core/static/js/extensions.js', +]; + +// on activation we clean up the previously registered service workers +self.addEventListener('activate', evt => + evt.waitUntil( + caches.keys().then(cacheNames => { + return Promise.all( + cacheNames.map(cacheName => { + if (cacheName !== CURRENT_CACHE) { + return caches.delete(cacheName); + } + }) + ); + }) + ) +); + +// on install we download the routes we want to cache for offline +self.addEventListener('install', evt => + evt.waitUntil( + caches.open(CURRENT_CACHE).then(cache => { + return cache.addAll(cacheFiles); + }) + ) +); + +// fetch the resource from the network +const fromNetwork = (request, timeout) => + new Promise((fulfill, reject) => { + const timeoutId = setTimeout(reject, timeout); + fetch(request).then(response => { + clearTimeout(timeoutId); + fulfill(response); + update(request); + }, reject); + }); + +// fetch the resource from the browser cache +const fromCache = request => + caches + .open(CURRENT_CACHE) + .then(cache => + cache + .match(request) + .then(matching => matching || cache.match('/offline/')) + ); + +// cache the current page to make it available for offline +const update = request => + caches + .open(CURRENT_CACHE) + .then(cache => + fetch(request).then(response => cache.put(request, response)) + ); + +// general strategy when making a request (eg if online try to fetch it +// from the network with a timeout, if something fails serve from cache) +self.addEventListener('fetch', evt => { + evt.respondWith( + fromNetwork(evt.request, 10000).catch(() => fromCache(evt.request)) + ); + evt.waitUntil(update(evt.request)); +}); \ No newline at end of file diff --git a/lnbits/core/static/js/wallet.js b/lnbits/core/static/js/wallet.js index 29a1025da..057968938 100644 --- a/lnbits/core/static/js/wallet.js +++ b/lnbits/core/static/js/wallet.js @@ -702,3 +702,10 @@ new Vue({ ) } }) + +if (navigator.serviceWorker != null) { + navigator.serviceWorker.register('/service-worker.js') + .then(function(registration) { + console.log('Registered events at scope: ', registration.scope); + }); +} \ No newline at end of file diff --git a/lnbits/core/templates/core/wallet.html b/lnbits/core/templates/core/wallet.html index db4358664..e705f3736 100644 --- a/lnbits/core/templates/core/wallet.html +++ b/lnbits/core/templates/core/wallet.html @@ -1,10 +1,10 @@ + {% extends "base.html" %} {% from "macros.jinja" import window_vars with context %} {% block scripts %} {{ window_vars(user, wallet) }} - {% endblock %} {% block title %} {{ wallet.name }} - {{ SITE_TITLE }} {% endblock %} diff --git a/lnbits/core/views/generic.py b/lnbits/core/views/generic.py index d9687e160..615de1e9f 100644 --- a/lnbits/core/views/generic.py +++ b/lnbits/core/views/generic.py @@ -17,6 +17,7 @@ from lnbits.helpers import template_renderer, url_for from lnbits.settings import ( LNBITS_ADMIN_USERS, LNBITS_ALLOWED_USERS, + LNBITS_CUSTOM_LOGO, LNBITS_SITE_TITLE, SERVICE_FEE, ) @@ -251,6 +252,10 @@ async def lnurlwallet(request: Request): ) +@core_html_routes.get("/service-worker.js", response_class=FileResponse) +async def service_worker(): + return FileResponse("lnbits/core/static/js/service-worker.js") + @core_html_routes.get("/manifest/{usr}.webmanifest") async def manifest(usr: str): user = await get_user(usr) @@ -258,21 +263,21 @@ async def manifest(usr: str): raise HTTPException(status_code=HTTPStatus.NOT_FOUND) return { - "short_name": "LNbits", - "name": "LNbits Wallet", + "short_name": LNBITS_SITE_TITLE, + "name": LNBITS_SITE_TITLE + " Wallet", "icons": [ { - "src": "https://cdn.jsdelivr.net/gh/lnbits/lnbits@0.3.0/docs/logos/lnbits.png", + "src": LNBITS_CUSTOM_LOGO if LNBITS_CUSTOM_LOGO else "https://cdn.jsdelivr.net/gh/lnbits/lnbits@0.3.0/docs/logos/lnbits.png", "type": "image/png", "sizes": "900x900", } ], - "start_url": "/wallet?usr=" + usr, - "background_color": "#3367D6", - "description": "Weather forecast information", + "start_url": "/wallet?usr=" + usr + "&wal=" + user.wallets[0].id, + "background_color": "#1F2234", + "description": "Bitcoin Lightning Wallet", "display": "standalone", "scope": "/", - "theme_color": "#3367D6", + "theme_color": "#1F2234", "shortcuts": [ { "name": wallet.name, From d88ffeb23777f5e09e63ca866b85c47f02af781e Mon Sep 17 00:00:00 2001 From: Lee Salminen Date: Mon, 4 Jul 2022 12:32:28 -0600 Subject: [PATCH 2/8] segregate cache by api key header --- lnbits/core/static/js/service-worker.js | 26 ++++++++----------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/lnbits/core/static/js/service-worker.js b/lnbits/core/static/js/service-worker.js index 3ff181948..c8b7a7a13 100644 --- a/lnbits/core/static/js/service-worker.js +++ b/lnbits/core/static/js/service-worker.js @@ -1,12 +1,10 @@ // the cache version gets updated every time there is a new deployment const CACHE_VERSION = 1; -const CURRENT_CACHE = `lnbits-${CACHE_VERSION}`; +const CURRENT_CACHE = `lnbits-${CACHE_VERSION}-`; -// these are the routes we are going to cache for offline support -const cacheFiles = [ - '/core/static/js/wallet.js', - '/core/static/js/extensions.js', -]; +const getApiKey = (request) => { + return request.headers.get('X-Api-Key') || "none" +} // on activation we clean up the previously registered service workers self.addEventListener('activate', evt => @@ -14,7 +12,8 @@ self.addEventListener('activate', evt => caches.keys().then(cacheNames => { return Promise.all( cacheNames.map(cacheName => { - if (cacheName !== CURRENT_CACHE) { + const currentCacheVersion = cacheName.split('-').slice(-2) + if (currentCacheVersion !== CACHE_VERSION) { return caches.delete(cacheName); } }) @@ -23,15 +22,6 @@ self.addEventListener('activate', evt => ) ); -// on install we download the routes we want to cache for offline -self.addEventListener('install', evt => - evt.waitUntil( - caches.open(CURRENT_CACHE).then(cache => { - return cache.addAll(cacheFiles); - }) - ) -); - // fetch the resource from the network const fromNetwork = (request, timeout) => new Promise((fulfill, reject) => { @@ -46,7 +36,7 @@ const fromNetwork = (request, timeout) => // fetch the resource from the browser cache const fromCache = request => caches - .open(CURRENT_CACHE) + .open(CURRENT_CACHE + getApiKey(request)) .then(cache => cache .match(request) @@ -56,7 +46,7 @@ const fromCache = request => // cache the current page to make it available for offline const update = request => caches - .open(CURRENT_CACHE) + .open(CURRENT_CACHE + getApiKey(request)) .then(cache => fetch(request).then(response => cache.put(request, response)) ); From b298e12cd37680861f97fc45cbfc114448e1a6b0 Mon Sep 17 00:00:00 2001 From: Lee Salminen Date: Mon, 4 Jul 2022 13:03:21 -0600 Subject: [PATCH 3/8] add offline indicator --- lnbits/static/js/base.js | 11 ++++++++++- lnbits/templates/base.html | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lnbits/static/js/base.js b/lnbits/static/js/base.js index c8863b5ab..de70b2888 100644 --- a/lnbits/static/js/base.js +++ b/lnbits/static/js/base.js @@ -315,6 +315,7 @@ window.windowMixin = { data: function () { return { g: { + offline: !navigator.onLine, visibleDrawer: false, extensions: [], user: null, @@ -354,6 +355,14 @@ window.windowMixin = { } this.g.allowedThemes = window.allowedThemes ?? ['bitcoin'] + addEventListener('offline', event => { + this.g.offline = true + }) + + addEventListener('online', event => { + this.g.offline = false + }) + // failsafe if admin changes themes halfway if (!this.$q.localStorage.getItem('lnbits.theme')){ this.changeColor(this.g.allowedThemes[0]) @@ -432,4 +441,4 @@ window.decryptLnurlPayAES = function (success_action, preimage) { let decoder = new TextDecoder('utf-8') return decoder.decode(valueb) }) -} +} \ No newline at end of file diff --git a/lnbits/templates/base.html b/lnbits/templates/base.html index bf29bce68..b36462962 100644 --- a/lnbits/templates/base.html +++ b/lnbits/templates/base.html @@ -51,6 +51,11 @@ > {% endblock %} + + + OFFLINE + + Date: Mon, 4 Jul 2022 14:17:46 -0600 Subject: [PATCH 4/8] reduce noise --- lnbits/core/static/js/service-worker.js | 54 +++++++++---------------- 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/lnbits/core/static/js/service-worker.js b/lnbits/core/static/js/service-worker.js index c8b7a7a13..4f0addc22 100644 --- a/lnbits/core/static/js/service-worker.js +++ b/lnbits/core/static/js/service-worker.js @@ -12,7 +12,7 @@ self.addEventListener('activate', evt => caches.keys().then(cacheNames => { return Promise.all( cacheNames.map(cacheName => { - const currentCacheVersion = cacheName.split('-').slice(-2) + const currentCacheVersion = cacheName.split('-').slice(-2, 2) if (currentCacheVersion !== CACHE_VERSION) { return caches.delete(cacheName); } @@ -22,40 +22,24 @@ self.addEventListener('activate', evt => ) ); -// fetch the resource from the network -const fromNetwork = (request, timeout) => - new Promise((fulfill, reject) => { - const timeoutId = setTimeout(reject, timeout); - fetch(request).then(response => { - clearTimeout(timeoutId); - fulfill(response); - update(request); - }, reject); - }); +// The fetch handler serves responses for same-origin resources from a cache. +// If no response is found, it populates the runtime cache with the response +// from the network before returning it to the page. +self.addEventListener('fetch', event => { + // Skip cross-origin requests, like those for Google Analytics. + if (event.request.url.startsWith(self.location.origin) && event.request.method == "GET") { -// fetch the resource from the browser cache -const fromCache = request => - caches - .open(CURRENT_CACHE + getApiKey(request)) - .then(cache => - cache - .match(request) - .then(matching => matching || cache.match('/offline/')) - ); + // Open the cache + event.respondWith(caches.open(CURRENT_CACHE + getApiKey(event.request)).then((cache) => { + // Go to the network first + return fetch(event.request).then((fetchedResponse) => { + cache.put(event.request, fetchedResponse.clone()); -// cache the current page to make it available for offline -const update = request => - caches - .open(CURRENT_CACHE + getApiKey(request)) - .then(cache => - fetch(request).then(response => cache.put(request, response)) - ); - -// general strategy when making a request (eg if online try to fetch it -// from the network with a timeout, if something fails serve from cache) -self.addEventListener('fetch', evt => { - evt.respondWith( - fromNetwork(evt.request, 10000).catch(() => fromCache(evt.request)) - ); - evt.waitUntil(update(evt.request)); + return fetchedResponse; + }).catch(() => { + // If the network is unavailable, get + return cache.match(event.request.url); + }); + })); + } }); \ No newline at end of file From 56c60587a1b3c23201c6c494f8635949d5bc2a88 Mon Sep 17 00:00:00 2001 From: Lee Salminen Date: Tue, 5 Jul 2022 09:14:24 -0600 Subject: [PATCH 5/8] fix prettier --- lnbits/core/views/generic.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lnbits/core/views/generic.py b/lnbits/core/views/generic.py index 615de1e9f..57096b47a 100644 --- a/lnbits/core/views/generic.py +++ b/lnbits/core/views/generic.py @@ -256,6 +256,7 @@ async def lnurlwallet(request: Request): async def service_worker(): return FileResponse("lnbits/core/static/js/service-worker.js") + @core_html_routes.get("/manifest/{usr}.webmanifest") async def manifest(usr: str): user = await get_user(usr) @@ -267,7 +268,9 @@ async def manifest(usr: str): "name": LNBITS_SITE_TITLE + " Wallet", "icons": [ { - "src": LNBITS_CUSTOM_LOGO if LNBITS_CUSTOM_LOGO else "https://cdn.jsdelivr.net/gh/lnbits/lnbits@0.3.0/docs/logos/lnbits.png", + "src": LNBITS_CUSTOM_LOGO + if LNBITS_CUSTOM_LOGO + else "https://cdn.jsdelivr.net/gh/lnbits/lnbits@0.3.0/docs/logos/lnbits.png", "type": "image/png", "sizes": "900x900", } From 2cb87d96f23ecb9b3c37a9f0dc11c948762e5d52 Mon Sep 17 00:00:00 2001 From: Lee Salminen Date: Tue, 5 Jul 2022 15:05:31 -0600 Subject: [PATCH 6/8] better way of handling injection of webmanifests --- lnbits/core/templates/core/wallet.html | 1 - lnbits/core/views/generic.py | 1 + lnbits/templates/base.html | 4 ++++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lnbits/core/templates/core/wallet.html b/lnbits/core/templates/core/wallet.html index e705f3736..acfcf7004 100644 --- a/lnbits/core/templates/core/wallet.html +++ b/lnbits/core/templates/core/wallet.html @@ -1,4 +1,3 @@ - {% extends "base.html" %} {% from "macros.jinja" import window_vars with context %} diff --git a/lnbits/core/views/generic.py b/lnbits/core/views/generic.py index 57096b47a..35f3c1e3f 100644 --- a/lnbits/core/views/generic.py +++ b/lnbits/core/views/generic.py @@ -145,6 +145,7 @@ async def wallet( "user": user.dict(), "wallet": wallet.dict(), "service_fee": service_fee, + "web_manifest": f"/manifest/{user.id}.webmanifest" }, ) diff --git a/lnbits/templates/base.html b/lnbits/templates/base.html index b36462962..a744e1346 100644 --- a/lnbits/templates/base.html +++ b/lnbits/templates/base.html @@ -16,6 +16,10 @@ /> + {% if web_manifest %} + + {% endif %} + {% block head_scripts %}{% endblock %} From ebeb3d213b314501afb80c4fba44eeac72ace0a3 Mon Sep 17 00:00:00 2001 From: Lee Salminen Date: Tue, 5 Jul 2022 15:08:57 -0600 Subject: [PATCH 7/8] alter injection of tpos to match --- lnbits/core/views/generic.py | 2 +- lnbits/extensions/tpos/templates/tpos/tpos.html | 1 - lnbits/extensions/tpos/views.py | 7 ++++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lnbits/core/views/generic.py b/lnbits/core/views/generic.py index 35f3c1e3f..f8b98e4c6 100644 --- a/lnbits/core/views/generic.py +++ b/lnbits/core/views/generic.py @@ -145,7 +145,7 @@ async def wallet( "user": user.dict(), "wallet": wallet.dict(), "service_fee": service_fee, - "web_manifest": f"/manifest/{user.id}.webmanifest" + "web_manifest": f"/manifest/{user.id}.webmanifest", }, ) diff --git a/lnbits/extensions/tpos/templates/tpos/tpos.html b/lnbits/extensions/tpos/templates/tpos/tpos.html index e4ea14992..02d6a98d6 100644 --- a/lnbits/extensions/tpos/templates/tpos/tpos.html +++ b/lnbits/extensions/tpos/templates/tpos/tpos.html @@ -1,4 +1,3 @@ - {% extends "public.html" %} {% block toolbar_title %} {{ tpos.name }} diff --git a/lnbits/extensions/tpos/views.py b/lnbits/extensions/tpos/views.py index a94564d57..21a471c4a 100644 --- a/lnbits/extensions/tpos/views.py +++ b/lnbits/extensions/tpos/views.py @@ -35,7 +35,12 @@ async def tpos(request: Request, tpos_id): ) return tpos_renderer().TemplateResponse( - "tpos/tpos.html", {"request": request, "tpos": tpos} + "tpos/tpos.html", + { + "request": request, + "tpos": tpos, + "web_manifest": f"/tpos/manifest/{tpos_id}.webmanifest", + }, ) From 94e4495026b0cb2faa186b660e0b48f33e2ab726 Mon Sep 17 00:00:00 2001 From: Lee Salminen Date: Tue, 5 Jul 2022 16:16:46 -0600 Subject: [PATCH 8/8] run prettier --- lnbits/core/static/js/service-worker.js | 46 ++++++++------ lnbits/core/static/js/wallet.js | 11 ++-- .../extensions/tpos/templates/tpos/tpos.html | 62 +++++++++---------- lnbits/static/js/base.js | 4 +- lnbits/templates/base.html | 17 ++--- 5 files changed, 72 insertions(+), 68 deletions(-) diff --git a/lnbits/core/static/js/service-worker.js b/lnbits/core/static/js/service-worker.js index 4f0addc22..041b9f32f 100644 --- a/lnbits/core/static/js/service-worker.js +++ b/lnbits/core/static/js/service-worker.js @@ -1,9 +1,9 @@ // the cache version gets updated every time there is a new deployment -const CACHE_VERSION = 1; -const CURRENT_CACHE = `lnbits-${CACHE_VERSION}-`; +const CACHE_VERSION = 1 +const CURRENT_CACHE = `lnbits-${CACHE_VERSION}-` -const getApiKey = (request) => { - return request.headers.get('X-Api-Key') || "none" +const getApiKey = request => { + return request.headers.get('X-Api-Key') || 'none' } // on activation we clean up the previously registered service workers @@ -14,32 +14,38 @@ self.addEventListener('activate', evt => cacheNames.map(cacheName => { const currentCacheVersion = cacheName.split('-').slice(-2, 2) if (currentCacheVersion !== CACHE_VERSION) { - return caches.delete(cacheName); + return caches.delete(cacheName) } }) - ); + ) }) ) -); +) // The fetch handler serves responses for same-origin resources from a cache. // If no response is found, it populates the runtime cache with the response // from the network before returning it to the page. self.addEventListener('fetch', event => { // Skip cross-origin requests, like those for Google Analytics. - if (event.request.url.startsWith(self.location.origin) && event.request.method == "GET") { - + if ( + event.request.url.startsWith(self.location.origin) && + event.request.method == 'GET' + ) { // Open the cache - event.respondWith(caches.open(CURRENT_CACHE + getApiKey(event.request)).then((cache) => { - // Go to the network first - return fetch(event.request).then((fetchedResponse) => { - cache.put(event.request, fetchedResponse.clone()); + event.respondWith( + caches.open(CURRENT_CACHE + getApiKey(event.request)).then(cache => { + // Go to the network first + return fetch(event.request) + .then(fetchedResponse => { + cache.put(event.request, fetchedResponse.clone()) - return fetchedResponse; - }).catch(() => { - // If the network is unavailable, get - return cache.match(event.request.url); - }); - })); + return fetchedResponse + }) + .catch(() => { + // If the network is unavailable, get + return cache.match(event.request.url) + }) + }) + ) } -}); \ No newline at end of file +}) diff --git a/lnbits/core/static/js/wallet.js b/lnbits/core/static/js/wallet.js index 057968938..baa9f605f 100644 --- a/lnbits/core/static/js/wallet.js +++ b/lnbits/core/static/js/wallet.js @@ -704,8 +704,9 @@ new Vue({ }) if (navigator.serviceWorker != null) { - navigator.serviceWorker.register('/service-worker.js') - .then(function(registration) { - console.log('Registered events at scope: ', registration.scope); - }); -} \ No newline at end of file + navigator.serviceWorker + .register('/service-worker.js') + .then(function (registration) { + console.log('Registered events at scope: ', registration.scope) + }) +} diff --git a/lnbits/extensions/tpos/templates/tpos/tpos.html b/lnbits/extensions/tpos/templates/tpos/tpos.html index 02d6a98d6..ca196e4a0 100644 --- a/lnbits/extensions/tpos/templates/tpos/tpos.html +++ b/lnbits/extensions/tpos/templates/tpos/tpos.html @@ -1,6 +1,4 @@ -{% extends "public.html" %} -{% block toolbar_title %} -{{ tpos.name }} +{% extends "public.html" %} {% block toolbar_title %} {{ tpos.name }} -{% endblock %} -{% block footer %}{% endblock %} {% block page_container %} +{% endblock %} {% block footer %}{% endblock %} {% block page_container %} @@ -179,27 +176,24 @@ - +
- Would you like to leave a tip? + Would you like to leave a tip?
- {% raw %}{{ tip }}{% endraw %}% + {% raw %}{{ tip }}{% endraw %}%

No, thanks

@@ -264,7 +258,7 @@ } .keypad .btn-confirm { - grid-area: 1 / 4 / 5 / 4; + grid-area: 1 / 4 / 5 / 4; } {% endblock %} {% block scripts %} @@ -281,7 +275,7 @@ tip_options: JSON.parse('{{ tpos.tip_options }}'), exchangeRate: null, stack: [], - tipAmount: 0.00, + tipAmount: 0.0, invoiceDialog: { show: false, data: null, @@ -289,7 +283,7 @@ paymentChecker: null }, tipDialog: { - show: false, + show: false }, urlDialog: { show: false @@ -323,7 +317,7 @@ methods: { closeInvoiceDialog: function () { this.stack = [] - this.tipAmount = 0.00 + this.tipAmount = 0.0 var dialog = this.invoiceDialog setTimeout(function () { clearInterval(dialog.paymentChecker) @@ -333,8 +327,10 @@ processTipSelection: function (selectedTipOption) { this.tipDialog.show = false - if(selectedTipOption) { - const tipAmount = parseFloat(parseFloat((selectedTipOption / 100) * this.amount)) + if (selectedTipOption) { + const tipAmount = parseFloat( + parseFloat((selectedTipOption / 100) * this.amount) + ) const subtotal = parseFloat(this.amount) const grandTotal = parseFloat((tipAmount + subtotal).toFixed(2)) const totalString = grandTotal.toFixed(2).toString() @@ -343,7 +339,7 @@ for (var i = 0; i < totalString.length; i++) { const char = totalString[i] - if(char !== ".") { + if (char !== '.') { this.stack.push(char) } } @@ -353,14 +349,14 @@ this.showInvoice() }, - submitForm: function() { - if(this.tip_options.length) { + submitForm: function () { + if (this.tip_options.length) { this.showTipModal() } else { this.showInvoice() } }, - showTipModal: function() { + showTipModal: function () { this.tipDialog.show = true }, showInvoice: function () { @@ -371,7 +367,7 @@ .post('/tpos/api/v1/tposs/' + this.tposId + '/invoices', null, { params: { amount: this.sat, - tipAmount: this.tipAmountSat, + tipAmount: this.tipAmountSat } }) .then(function (response) { diff --git a/lnbits/static/js/base.js b/lnbits/static/js/base.js index 48496b3c2..7c0e9958d 100644 --- a/lnbits/static/js/base.js +++ b/lnbits/static/js/base.js @@ -356,7 +356,7 @@ window.windowMixin = { } this.g.allowedThemes = window.allowedThemes ?? ['bitcoin'] - addEventListener('offline', event => { + addEventListener('offline', event => { this.g.offline = true }) @@ -442,4 +442,4 @@ window.decryptLnurlPayAES = function (success_action, preimage) { let decoder = new TextDecoder('utf-8') return decoder.decode(valueb) }) -} \ No newline at end of file +} diff --git a/lnbits/templates/base.html b/lnbits/templates/base.html index a744e1346..6ab1ec840 100644 --- a/lnbits/templates/base.html +++ b/lnbits/templates/base.html @@ -17,10 +17,8 @@ {% if web_manifest %} - - {% endif %} - - {% block head_scripts %}{% endblock %} + + {% endif %} {% block head_scripts %}{% endblock %} @@ -55,10 +53,13 @@ > {% endblock %} - - - OFFLINE - + + OFFLINE