From 369359daf3be6a7e623d6fff8e602a7be82bd024 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 3 Jan 2026 15:11:14 -0700 Subject: [PATCH] Add update popup --- app.js | 48 ++++++++++++++ bonus.webp | Bin 0 -> 12282 bytes style.css | 162 ++++++++++++++++++++++++++++++++++++++++++++++ workbox-config.js | 3 +- 4 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 bonus.webp diff --git a/app.js b/app.js index e95b3ce..82a4905 100644 --- a/app.js +++ b/app.js @@ -541,6 +541,35 @@ document.addEventListener('DOMContentLoaded', function () { let downloaderWorker = null; let missingGameFiles = []; + // Update popup elements + const updatePopup = document.getElementById('update-popup'); + const updateReloadBtn = document.getElementById('update-reload-btn'); + const updateDismissBtn = document.getElementById('update-dismiss-btn'); + + function showUpdatePopup() { + if (updatePopup) { + updatePopup.style.display = 'flex'; + } + } + + function hideUpdatePopup() { + if (updatePopup) { + updatePopup.style.display = 'none'; + } + } + + if (updateReloadBtn) { + updateReloadBtn.addEventListener('click', () => { + window.location.reload(); + }); + } + + if (updateDismissBtn) { + updateDismissBtn.addEventListener('click', () => { + hideUpdatePopup(); + }); + } + if ('serviceWorker' in navigator) { Promise.all([ configManager.init(), @@ -548,6 +577,25 @@ document.addEventListener('DOMContentLoaded', function () { ]).then(([configResult, swRegistration]) => { checkInitialCacheStatus(); showOrHideGraphicsOptions(); + + // Check if there's already a waiting service worker (update ready) + if (swRegistration.waiting) { + showUpdatePopup(); + } + + // Listen for new service worker updates + swRegistration.addEventListener('updatefound', () => { + const newWorker = swRegistration.installing; + if (newWorker) { + newWorker.addEventListener('statechange', () => { + // When the new worker is installed and waiting, show the update popup + // Only show if there's an existing controller (this is an update, not first install) + if (newWorker.state === 'installed' && navigator.serviceWorker.controller) { + showUpdatePopup(); + } + }); + } + }); }).catch(error => { console.error('Initialization failed:', error); }); diff --git a/bonus.webp b/bonus.webp new file mode 100644 index 0000000000000000000000000000000000000000..dd388ac7e9205e7163ce39f49a98a012a738d64c GIT binary patch literal 12282 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 literal 0 HcmV?d00001 diff --git a/style.css b/style.css index f12dc7b..900231a 100644 --- a/style.css +++ b/style.css @@ -1136,4 +1136,166 @@ select { opacity: 0; transform: translate(var(--tx), var(--ty)) rotate(var(--rot)) scale(0.5); } +} + +/* Update notification popup */ +.update-popup { + position: fixed; + bottom: 20px; + right: 20px; + z-index: 10001; + display: flex; + align-items: flex-end; + gap: 0; + animation: popup-bounce 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); +} + +@keyframes popup-bounce { + 0% { + transform: translateX(120%); + opacity: 0; + } + 100% { + transform: translateX(0); + opacity: 1; + } +} + +.update-popup-content { + position: relative; + display: flex; + flex-direction: column; + align-items: flex-end; +} + +.update-speech-bubble { + position: relative; + background: linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 100%); + border: 2px solid #FFD700; + border-radius: 12px; + padding: 15px 18px; + margin-bottom: 10px; + margin-right: -20px; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.4); + max-width: 200px; +} + +.update-speech-bubble::after { + content: ''; + position: absolute; + bottom: -12px; + right: 30px; + border-width: 12px 10px 0 10px; + border-style: solid; + border-color: #FFD700 transparent transparent transparent; +} + +.update-speech-bubble::before { + content: ''; + position: absolute; + bottom: -8px; + right: 32px; + border-width: 10px 8px 0 8px; + border-style: solid; + border-color: #1a1a1a transparent transparent transparent; + z-index: 1; +} + +.update-message { + color: #f0f0f0; + font-size: 0.95em; + font-weight: 500; + margin: 0 0 12px 0; + line-height: 1.4; +} + +.update-reload-btn { + width: 100%; + padding: 10px 16px; + background-color: #FFD700; + color: #000; + border: none; + border-radius: 6px; + font-size: 0.9em; + font-weight: bold; + cursor: pointer; + transition: all 0.2s ease; +} + +.update-reload-btn:hover { + background-color: #fff; + transform: scale(1.03); +} + +.update-dismiss-btn { + position: absolute; + top: -8px; + right: -8px; + width: 24px; + height: 24px; + padding: 0; + background: #333; + color: #888; + border: 2px solid #555; + border-radius: 50%; + font-size: 14px; + line-height: 1; + cursor: pointer; + transition: all 0.2s ease; + display: flex; + align-items: center; + justify-content: center; + z-index: 2; +} + +.update-dismiss-btn:hover { + color: #fff; + border-color: #FFD700; + background: #444; +} + +.update-character { + width: 120px; + height: auto; + border-radius: 12px; + filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.5)); + animation: character-wave 2s ease-in-out infinite; + animation-delay: 0.5s; +} + +@keyframes character-wave { + 0%, 100% { + transform: rotate(0deg); + } + 25% { + transform: rotate(2deg); + } + 75% { + transform: rotate(-2deg); + } +} + +@media (max-width: 480px) { + .update-popup { + bottom: 10px; + right: 10px; + } + + .update-speech-bubble { + max-width: 160px; + margin-right: -15px; + } + + .update-character { + width: 90px; + } + + .update-message { + font-size: 0.85em; + } + + .update-reload-btn { + font-size: 0.85em; + padding: 8px 12px; + } } \ No newline at end of file diff --git a/workbox-config.js b/workbox-config.js index f31828c..f9c0294 100644 --- a/workbox-config.js +++ b/workbox-config.js @@ -7,7 +7,8 @@ module.exports = { 'island.webp', 'isle.js', 'isle.wasm', 'poster.pdf', 'read_me_off.webp', 'read_me_on.webp', 'run_game_off.webp', 'run_game_on.webp', 'shark.webp', 'uninstall_off.webp', 'uninstall_on.webp', 'app.js', 'style.css', 'manifest.json', - 'install.webp', 'install.mp3', 'downloader.js', 'debug.js', 'debug.html', 'ogel.webp' + 'install.webp', 'install.mp3', 'downloader.js', 'debug.js', 'debug.html', 'ogel.webp', + 'bonus.webp' ], swSrc: 'src/sw.js', swDest: 'sw.js',