PWA install button added

This commit is contained in:
Трошин Антон Валерьевич
2026-07-12 02:46:20 +03:00
parent 45734bb5b4
commit 0649d05bb0
4 changed files with 33 additions and 5 deletions
+27
View File
@@ -32,6 +32,7 @@ const STRINGS = {
pctCorrect: '{pct}% correct', pctCorrect: '{pct}% correct',
congratulations: 'Congratulations!', congratulations: 'Congratulations!',
pleaseSelect: 'Please select all options', pleaseSelect: 'Please select all options',
installApp: 'Install App',
systemNames: { systemNames: {
binary: 'Binary', octal: 'Octal', hex: 'Hexadecimal', binary: 'Binary', octal: 'Octal', hex: 'Hexadecimal',
ternary: 'Balanced Ternary', braille: 'Braille Decimal', ternary: 'Balanced Ternary', braille: 'Braille Decimal',
@@ -68,6 +69,7 @@ const STRINGS = {
pctCorrect: '{pct}% \u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u044B\u0445', pctCorrect: '{pct}% \u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u044B\u0445',
congratulations: '\u041F\u043E\u0437\u0434\u0440\u0430\u0432\u043B\u044F\u0435\u043C!', 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', 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: { systemNames: {
binary: '\u0414\u0432\u043E\u0438\u0447\u043D\u0430\u044F', binary: '\u0414\u0432\u043E\u0438\u0447\u043D\u0430\u044F',
octal: '\u0412\u043E\u0441\u044C\u043C\u0435\u0440\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(); 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) { function showSetupMessage(msg) {
const containers = document.querySelectorAll('.setup-container'); const containers = document.querySelectorAll('.setup-container');
let el = document.getElementById('setup-message'); let el = document.getElementById('setup-message');
+4 -3
View File
@@ -10,7 +10,7 @@
<link rel="manifest" href="manifest.json"> <link rel="manifest" href="manifest.json">
<link rel="icon" type="image/svg+xml" href="icon.svg"> <link rel="icon" type="image/svg+xml" href="icon.svg">
<link rel="apple-touch-icon" href="icon-192.png"> <link rel="apple-touch-icon" href="icon-192.png">
<link rel="stylesheet" href="styles.css?v=34"> <link rel="stylesheet" href="styles.css?v=35">
</head> </head>
<body> <body>
<div id="app"> <div id="app">
@@ -28,6 +28,7 @@
<option value="en">English</option> <option value="en">English</option>
<option value="ru">Русский</option> <option value="ru">Русский</option>
</select> </select>
<button class="btn btn-secondary btn-large hidden" id="btn-install" data-i18n="installApp">Install App</button>
</div> </div>
</div> </div>
@@ -154,10 +155,10 @@
</div> </div>
<script type="module" src="app.js?v=34"></script> <script type="module" src="app.js?v=35"></script>
<script> <script>
if ('serviceWorker' in navigator) { if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js?v=34').catch(() => {}); navigator.serviceWorker.register('/sw.js?v=35').catch(() => {});
} }
</script> </script>
</body> </body>
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "NumNum", "name": "NumNum",
"short_name": "NumNum", "short_name": "NumNum",
"description": "Train your numeric systems", "description": "Numeral systems trainer",
"start_url": "/", "start_url": "/",
"display": "standalone", "display": "standalone",
"orientation": "portrait", "orientation": "portrait",
+1 -1
View File
@@ -1,4 +1,4 @@
const CACHE_NAME = 'numnum-v34'; const CACHE_NAME = 'numnum-v35';
const ASSETS = [ const ASSETS = [
'/', '/',
'/index.html', '/index.html',