From 0649d05bb0b96a07095e7a3aa85aeb47e79cc7d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D1=80=D0=BE=D1=88=D0=B8=D0=BD=20=D0=90=D0=BD=D1=82?= =?UTF-8?q?=D0=BE=D0=BD=20=D0=92=D0=B0=D0=BB=D0=B5=D1=80=D1=8C=D0=B5=D0=B2?= =?UTF-8?q?=D0=B8=D1=87?= Date: Sun, 12 Jul 2026 02:46:20 +0300 Subject: [PATCH] PWA install button added --- app.js | 27 +++++++++++++++++++++++++++ index.html | 7 ++++--- manifest.json | 2 +- sw.js | 2 +- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/app.js b/app.js index e412a0d..c32acfc 100644 --- a/app.js +++ b/app.js @@ -32,6 +32,7 @@ const STRINGS = { pctCorrect: '{pct}% correct', congratulations: 'Congratulations!', pleaseSelect: 'Please select all options', + installApp: 'Install App', systemNames: { binary: 'Binary', octal: 'Octal', hex: 'Hexadecimal', ternary: 'Balanced Ternary', braille: 'Braille Decimal', @@ -68,6 +69,7 @@ const STRINGS = { pctCorrect: '{pct}% \u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u044B\u0445', congratulations: '\u041F\u043E\u0437\u0434\u0440\u0430\u0432\u043B\u044F\u0435\u043C!', pleaseSelect: '\u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0432\u0441\u0435 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B', + installApp: '\u0423\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435', systemNames: { binary: '\u0414\u0432\u043E\u0438\u0447\u043D\u0430\u044F', octal: '\u0412\u043E\u0441\u044C\u043C\u0435\u0440\u0438\u0447\u043D\u0430\u044F', @@ -667,6 +669,31 @@ langSelect.addEventListener('change', () => { applyTranslations(); +let deferredPrompt = null; + +window.addEventListener('beforeinstallprompt', (e) => { + e.preventDefault(); + deferredPrompt = e; + document.getElementById('btn-install').classList.remove('hidden'); +}); + +document.getElementById('btn-install').addEventListener('click', async () => { + if (!deferredPrompt) return; + deferredPrompt.prompt(); + await deferredPrompt.userChoice; + deferredPrompt = null; + document.getElementById('btn-install').classList.add('hidden'); +}); + +window.addEventListener('appinstalled', () => { + deferredPrompt = null; + document.getElementById('btn-install').classList.add('hidden'); +}); + +if (window.matchMedia('(display-mode: standalone)').matches || navigator.standalone) { + document.getElementById('btn-install').classList.add('hidden'); +} + function showSetupMessage(msg) { const containers = document.querySelectorAll('.setup-container'); let el = document.getElementById('setup-message'); diff --git a/index.html b/index.html index e1aed7f..52be821 100644 --- a/index.html +++ b/index.html @@ -10,7 +10,7 @@ - +
@@ -28,6 +28,7 @@ +
@@ -154,10 +155,10 @@ - + diff --git a/manifest.json b/manifest.json index 75da91c..754667a 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "NumNum", "short_name": "NumNum", - "description": "Train your numeric systems", + "description": "Numeral systems trainer", "start_url": "/", "display": "standalone", "orientation": "portrait", diff --git a/sw.js b/sw.js index 525c332..ef2b404 100644 --- a/sw.js +++ b/sw.js @@ -1,4 +1,4 @@ -const CACHE_NAME = 'numnum-v34'; +const CACHE_NAME = 'numnum-v35'; const ASSETS = [ '/', '/index.html',