From e96ba299b7114bd1910536f43db01c4ef6b54994 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sun, 4 Jan 2026 15:31:19 -0700 Subject: [PATCH] Update config page --- app.js | 110 +++++++++ index.html | 643 ++++++++++++++++++++++++----------------------------- style.css | 287 ++++++++++++++++++++++-- sw.js | 2 +- 4 files changed, 679 insertions(+), 363 deletions(-) diff --git a/app.js b/app.js index 17d677c..9142271 100644 --- a/app.js +++ b/app.js @@ -271,6 +271,113 @@ document.addEventListener('DOMContentLoaded', function () { }); }); + // --- Configure Tabs --- + const configTabButtons = document.querySelectorAll('.config-tab-btn'); + const configTabPanels = document.querySelectorAll('.config-tab-panel'); + + configTabButtons.forEach(button => { + button.addEventListener('click', () => { + const targetTab = button.dataset.configTab; + configTabButtons.forEach(btn => btn.classList.remove('active')); + button.classList.add('active'); + configTabPanels.forEach(panel => { + panel.classList.remove('active'); + if (panel.id === 'config-tab-' + targetTab) { + panel.classList.add('active'); + // Open first section, close others + const sections = panel.querySelectorAll('.config-section-card'); + sections.forEach((section, index) => { + section.open = (index === 0); + }); + } + }); + }); + }); + + // --- Accordion behavior for config sections --- + const configSections = document.querySelectorAll('.config-section-card'); + configSections.forEach(section => { + const summary = section.querySelector('summary'); + if (summary) { + summary.addEventListener('click', (e) => { + // If this section is closed and about to open, close others first + if (!section.open) { + configSections.forEach(other => { + if (other !== section && other.open) { + other.open = false; + } + }); + } + }); + } + }); + + // --- Preset Buttons --- + const presetClassic = document.getElementById('preset-classic'); + const presetModern = document.getElementById('preset-modern'); + + function applyPreset(preset) { + if (preset === 'classic') { + // Game section defaults + document.getElementById('language-select').value = 'en'; + document.getElementById('window-windowed').checked = true; + document.getElementById('aspect-original').checked = true; + document.getElementById('resolution-original').checked = true; + // Detail section defaults + document.getElementById('gfx-high').checked = true; + document.getElementById('tex-high').checked = true; + document.getElementById('max-lod').value = '3.6'; + document.getElementById('max-allowed-extras').value = '20'; + // Disable all extensions + document.getElementById('check-hd-textures').checked = false; + document.getElementById('check-hd-music').checked = false; + document.getElementById('check-widescreen-bgs').checked = false; + document.getElementById('check-outro').checked = false; + document.getElementById('check-ending').checked = false; + } else if (preset === 'modern') { + document.getElementById('aspect-wide').checked = true; + document.getElementById('resolution-wide').checked = true; + document.getElementById('gfx-high').checked = true; + document.getElementById('tex-high').checked = true; + document.getElementById('max-lod').value = '6'; + document.getElementById('max-allowed-extras').value = '40'; + // Enable HD extensions + document.getElementById('check-hd-textures').checked = true; + document.getElementById('check-hd-music').checked = true; + document.getElementById('check-widescreen-bgs').checked = true; + } + // Trigger change event to save config + const configForm = document.getElementById('config-form'); + if (configForm) { + configForm.dispatchEvent(new Event('change')); + } + // Refresh Offline Play button state + if (typeof checkInitialCacheStatus === 'function') { + checkInitialCacheStatus(); + } + } + + if (presetClassic) { + presetClassic.addEventListener('click', () => applyPreset('classic')); + } + if (presetModern) { + presetModern.addEventListener('click', () => applyPreset('modern')); + } + + // --- Config Toast --- + const configToast = document.getElementById('config-toast'); + let toastTimeout = null; + + function showConfigToast() { + if (configToast) { + configToast.classList.add('show'); + if (toastTimeout) clearTimeout(toastTimeout); + toastTimeout = setTimeout(() => { + configToast.classList.remove('show'); + }, 2000); + } + } + window.addEventListener('popstate', (e) => { if (e.state && e.state.page && e.state.page !== 'main') { showPage(e.state.page, false); @@ -402,6 +509,9 @@ document.addEventListener('DOMContentLoaded', function () { console.log(e.data.message); URL.revokeObjectURL(workerUrl); // Clean up the temporary URL worker.terminate(); + if (e.data.status === 'success') { + showConfigToast(); + } }; worker.onerror = (e) => { diff --git a/index.html b/index.html index f1bf7d8..18b7c54 100644 --- a/index.html +++ b/index.html @@ -424,364 +424,311 @@

OPFS is disabled in this browser. Default configuration will apply. If you are using a Firefox Private window, please change to a regular window instead to change configuration.

-
+
LEGO Island Shark and Brickster
-
-
-

Game

-
-
- -
- -
-
-
- -
-
- - -
-
- - -
-
-
-
- -
-
- - -
-
- - -
-
-
-
- -
-
- - -
-
- - -
-
-
-
+
+
+ +
-
-

Input

-
-
- -
- -
-
-
-
-
-

Detail

-
-
- -
-
- - -
-
- - -
-
- - -
-
-
-
- -
-
- - -
-
- - -
-
-
-
- - -
-
- - -
-
-
-
-

Graphics

-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
-
-

Sound

-
-
- -
-
- - -
-
- - -
-
-
-
-
-
-

- Extensions - ? - - Expands the game with new content and modifications created by the community. - - -

-
-
- -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-
-
-
-

Offline Play

-
-
-

Install for Offline Access

-

By installing, the game will be available to play even when you are not connected to - the internet. This will download all necessary files to your device (about 550MB in - size).

-

Note: browsers enforce strict storage and memory quotas, - especially when using private/incognito windows. If you encounter an error during - installation, please use a regular window and make sure you have enough disk space - available on your device.

-
-
- Install Game - -
-
-
- +
+
Settings saved
@@ -898,7 +845,7 @@
diff --git a/style.css b/style.css index dbb65e1..0bc1b40 100644 --- a/style.css +++ b/style.css @@ -338,7 +338,7 @@ body { text-decoration: underline; } -#configure-page .page-inner-content { +#configure-page .page-inner-content.config-layout { display: flex; background-color: #181818; border: 1px solid #303030; @@ -346,8 +346,9 @@ body { } .config-art-panel { - flex: 0 0 180px; + flex: 0 0 200px; border-radius: 8px 0 0 8px; + min-height: 420px; } .config-art-panel img { @@ -358,26 +359,258 @@ body { border-radius: 8px 0 0 8px; } +.config-main { + flex-grow: 1; + display: flex; + flex-direction: column; + padding: 20px; + min-width: 0; +} + .config-form { flex-grow: 1; - padding: 25px; } -.config-section { - margin-bottom: 25px; +/* Preset buttons */ +.config-presets { + display: flex; + gap: 10px; + margin-bottom: 15px; } -.config-section:last-child { +.preset-btn { + padding: 8px 16px; + background: linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 100%); + border: 1px solid #444; + border-radius: 6px; + color: #c0c0c0; + font-size: 0.85em; + font-weight: bold; + cursor: pointer; + transition: all 0.2s ease; +} + +.preset-btn:hover { + border-color: #FFD700; + color: #FFD700; + background: linear-gradient(135deg, #333 0%, #222 100%); +} + +.preset-btn:active { + transform: scale(0.98); +} + +/* Config tabs */ +.config-tabs { + flex-grow: 1; + display: flex; + flex-direction: column; +} + +.config-tab-buttons { + display: flex; + gap: 5px; + border-bottom: 1px solid #333; + margin-bottom: 15px; +} + +.config-tab-btn { + padding: 10px 18px; + background: transparent; + border: none; + border-bottom: 2px solid transparent; + color: #888; + font-size: 0.9em; + font-weight: bold; + cursor: pointer; + transition: all 0.2s ease; +} + +.config-tab-btn:hover { + color: #c0c0c0; +} + +.config-tab-btn.active { + color: #FFD700; + border-bottom-color: #FFD700; +} + +.config-tab-panel { + display: none; +} + +.config-tab-panel.active { + display: block; +} + +/* Collapsible section cards */ +.config-section-card { + background: linear-gradient(135deg, #1e1e1e 0%, #161616 100%); + border: 1px solid #2a2a2a; + border-radius: 8px; + margin-bottom: 12px; +} + +.config-section-card:last-child { margin-bottom: 0; } -.config-legend { +.config-card-header { + display: flex; + align-items: center; + gap: 8px; + padding: 12px 16px; color: #FFD700; - font-size: 1.1em; + font-size: 1em; font-weight: bold; - margin: 0 0 15px 0; - padding-bottom: 10px; - border-bottom: 1px solid #444; + cursor: pointer; + user-select: none; + list-style: none; +} + +.config-card-header::-webkit-details-marker { + display: none; +} + +.config-card-header::after { + content: '+'; + font-size: 1.2em; + color: #666; + transition: transform 0.2s ease; + margin-left: auto; +} + +.config-section-card[open] .config-card-header::after { + content: '−'; +} + +.config-card-content { + padding: 0 16px 16px 16px; +} + +/* Toggle switches */ +.toggle-group { + display: flex; + flex-direction: column; + gap: 12px; +} + +.toggle-switch { + display: flex; + align-items: center; + user-select: none; + min-width: 0; +} + +.toggle-switch label { + display: flex; + align-items: center; + cursor: pointer; +} + +.toggle-switch input { + position: absolute; + opacity: 0; + width: 0; + height: 0; +} + +.toggle-slider { + position: relative; + width: 44px; + height: 24px; + background-color: #333; + border-radius: 24px; + margin-right: 12px; + transition: background-color 0.2s ease; + flex-shrink: 0; +} + +.toggle-slider::after { + content: ''; + position: absolute; + top: 3px; + left: 3px; + width: 18px; + height: 18px; + background-color: #888; + border-radius: 50%; + transition: all 0.2s ease; +} + +.toggle-switch input:checked + .toggle-slider { + background-color: #3a5f3a; +} + +.toggle-switch input:checked + .toggle-slider::after { + left: 23px; + background-color: #FFD700; +} + +.toggle-label { + color: #c0c0c0; + font-size: 0.9em; + white-space: nowrap; +} + +@media (max-width: 768px) { + .toggle-label { + white-space: normal; + } +} + +.toggle-switch .tooltip-trigger { + margin-left: 8px; + flex-shrink: 0; +} + +.toggle-badge { + display: inline-block; + padding: 2px 6px; + margin-left: 8px; + background-color: #333; + border-radius: 4px; + font-size: 0.75em; + color: #888; +} + +@media (max-width: 768px) { + .toggle-badge { + display: none; + } +} + +/* Config toast notification */ +.config-toast { + position: fixed; + bottom: 20px; + left: 50%; + transform: translateX(-50%) translateY(100px); + background: linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 100%); + border: 1px solid #FFD700; + border-radius: 8px; + padding: 12px 24px; + color: #f0f0f0; + font-size: 0.9em; + font-weight: bold; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.4); + opacity: 0; + visibility: hidden; + transition: all 0.3s ease; + z-index: 10000; +} + +.config-toast.show { + transform: translateX(-50%) translateY(0); + opacity: 1; + visibility: visible; +} + +/* Offline play adjustments */ +.offline-note { + font-size: 0.75em; + color: #666; + margin-top: 8px; } .form-grid { @@ -428,7 +661,7 @@ body { line-height: 1.4; text-align: left; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); - z-index: 20; + z-index: 10000; opacity: 0; visibility: hidden; transition: opacity 0.2s, visibility 0.2s; @@ -1020,16 +1253,42 @@ select { display: none; } - #configure-page .page-inner-content { + #configure-page .page-inner-content.config-layout { background-color: transparent; border: none; padding: 0; } - .config-form { + .config-main { background-color: #181818; border: 1px solid #303030; border-radius: 8px; + padding: 15px; + } + + .config-presets { + flex-wrap: wrap; + } + + .preset-btn { + flex: 1; + text-align: center; + } + + .config-tab-buttons { + flex-wrap: wrap; + gap: 0; + } + + .config-tab-btn { + flex: 1 1 auto; + padding: 8px 12px; + font-size: 0.8em; + text-align: center; + } + + .form-grid { + grid-template-columns: 1fr; } .offline-play-grid { diff --git a/sw.js b/sw.js index f88c78f..60fb933 100644 --- a/sw.js +++ b/sw.js @@ -10,7 +10,7 @@ const { Strategy } = workbox.strategies; const { CacheableResponsePlugin } = workbox.cacheableResponse; const { RangeRequestsPlugin } = workbox.rangeRequests; -precacheAndRoute([{"revision":"483fcf29a509ff4578512ce6fd42194d","url":"index.html"},{"revision":"013ceb7d67293d532e979dde0347f3af","url":"cancel_off.webp"},{"revision":"bfc1563be018d82685716c6130529129","url":"cancel_on.webp"},{"revision":"d282c260fd35522036936bb6faf8ad21","url":"cdspin.gif"},{"revision":"3d820bf72b19bd4e437a61e75f317b83","url":"configure_off.webp"},{"revision":"e2c0c5e6aa1f7703c385a433a2d2a519","url":"configure_on.webp"},{"revision":"88e1e81c930d8e6c24dfdc7af274e812","url":"favicon.png"},{"revision":"d16b293eca457e2fb1e7ef2caca8c904","url":"favicon.svg"},{"revision":"d2b9c2e128ef1e5e4265c603b0bc3305","url":"free_stuff_off.webp"},{"revision":"cbc6a6779897f932c3a3c8dceb329804","url":"free_stuff_on.webp"},{"revision":"05fba4ef1884cbbd6afe09ea3325efc0","url":"install_off.webp"},{"revision":"11247e92082ba3d978a2e3785b0acf51","url":"install_on.webp"},{"revision":"d23ea8243c18eb217ef08fe607097824","url":"island.webp"},{"revision":"c97d78e159b8bff44d41e56d0aa20220","url":"isle.js"},{"revision":"5f174d45de1e3c5e0abdbccfd64567b6","url":"isle.wasm"},{"revision":"6d4248f1a08c218943e582673179b7be","url":"poster.pdf"},{"revision":"a6fcac24a24996545c039a1755af33ea","url":"read_me_off.webp"},{"revision":"aae783d064996b4322e23b092d97ea4a","url":"read_me_on.webp"},{"revision":"766a9e6e6d890f24cef252e81753b29d","url":"run_game_off.webp"},{"revision":"70208e00e9ea641e4c98699f74100db3","url":"run_game_on.webp"},{"revision":"0a65c71d9983c9bb1bc6a5f405fd6fd9","url":"shark.webp"},{"revision":"88c1fd032e6fc16814690712a26c1ede","url":"uninstall_off.webp"},{"revision":"0118a4aca04c5fb0a525bf00b001844e","url":"uninstall_on.webp"},{"revision":"008f544b125d0d595af8fffc2d86103d","url":"app.js"},{"revision":"8f37e9eaff5601153c160f0c8a9ab00e","url":"style.css"},{"revision":"060210979e13e305510de6285e085db1","url":"manifest.json"},{"revision":"4f0172bc7007d34cebf681cc233ab57f","url":"install.webp"},{"revision":"6a70d35dadf51d2ec6e38a6202d7fb0b","url":"install.mp3"},{"revision":"eac041a0b8835bfea706d997b0b7b224","url":"downloader.js"},{"revision":"6899f72755d4e84c707b93ac54a8fb06","url":"debug.js"},{"revision":"7817b36ddda9f07797c05a0ff6cacb21","url":"debug.html"},{"revision":"4ea2aac9446188b8a588811bc593919e","url":"ogel.webp"},{"revision":"c57d24598537443c5b8276c8dd5dbdc9","url":"bonus.webp"},{"revision":"d11c8c893d5525c8842555dc2861c393","url":"callfail.webp"},{"revision":"be9a89fb567b632cf8d4661cbf8afd9e","url":"getinfo.webp"},{"revision":"fe986681f41e96631f39f3288b23e538","url":"sysinfo.webp"},{"revision":"4ec902e0b0ce60ffd9dd565c9ddf40a1","url":"send.webp"},{"revision":"81f3c8fc38b876dc2fcfeefaadad1d1b","url":"congrats.webp"},{"revision":"f906318cb87e09a819e5916676caab2e","url":"register.webp"},{"revision":"c633a7500e6f30162bf1cf4ec4e95a6d","url":"later.webp"},{"revision":"d149d5709ac00fd5e2967ab4f3d74886","url":"comic.pdf"}]); +precacheAndRoute([{"revision":"77b36b116ba5ac49b416513c7d8e3a0c","url":"index.html"},{"revision":"013ceb7d67293d532e979dde0347f3af","url":"cancel_off.webp"},{"revision":"bfc1563be018d82685716c6130529129","url":"cancel_on.webp"},{"revision":"d282c260fd35522036936bb6faf8ad21","url":"cdspin.gif"},{"revision":"3d820bf72b19bd4e437a61e75f317b83","url":"configure_off.webp"},{"revision":"e2c0c5e6aa1f7703c385a433a2d2a519","url":"configure_on.webp"},{"revision":"88e1e81c930d8e6c24dfdc7af274e812","url":"favicon.png"},{"revision":"d16b293eca457e2fb1e7ef2caca8c904","url":"favicon.svg"},{"revision":"d2b9c2e128ef1e5e4265c603b0bc3305","url":"free_stuff_off.webp"},{"revision":"cbc6a6779897f932c3a3c8dceb329804","url":"free_stuff_on.webp"},{"revision":"05fba4ef1884cbbd6afe09ea3325efc0","url":"install_off.webp"},{"revision":"11247e92082ba3d978a2e3785b0acf51","url":"install_on.webp"},{"revision":"d23ea8243c18eb217ef08fe607097824","url":"island.webp"},{"revision":"c97d78e159b8bff44d41e56d0aa20220","url":"isle.js"},{"revision":"5f174d45de1e3c5e0abdbccfd64567b6","url":"isle.wasm"},{"revision":"6d4248f1a08c218943e582673179b7be","url":"poster.pdf"},{"revision":"a6fcac24a24996545c039a1755af33ea","url":"read_me_off.webp"},{"revision":"aae783d064996b4322e23b092d97ea4a","url":"read_me_on.webp"},{"revision":"766a9e6e6d890f24cef252e81753b29d","url":"run_game_off.webp"},{"revision":"70208e00e9ea641e4c98699f74100db3","url":"run_game_on.webp"},{"revision":"0a65c71d9983c9bb1bc6a5f405fd6fd9","url":"shark.webp"},{"revision":"88c1fd032e6fc16814690712a26c1ede","url":"uninstall_off.webp"},{"revision":"0118a4aca04c5fb0a525bf00b001844e","url":"uninstall_on.webp"},{"revision":"e8a8dd113d9bbfa2a1b81bbafa7b673d","url":"app.js"},{"revision":"debda137e612dedce0d0e7f7b545588f","url":"style.css"},{"revision":"060210979e13e305510de6285e085db1","url":"manifest.json"},{"revision":"4f0172bc7007d34cebf681cc233ab57f","url":"install.webp"},{"revision":"6a70d35dadf51d2ec6e38a6202d7fb0b","url":"install.mp3"},{"revision":"eac041a0b8835bfea706d997b0b7b224","url":"downloader.js"},{"revision":"6899f72755d4e84c707b93ac54a8fb06","url":"debug.js"},{"revision":"7817b36ddda9f07797c05a0ff6cacb21","url":"debug.html"},{"revision":"4ea2aac9446188b8a588811bc593919e","url":"ogel.webp"},{"revision":"c57d24598537443c5b8276c8dd5dbdc9","url":"bonus.webp"},{"revision":"d11c8c893d5525c8842555dc2861c393","url":"callfail.webp"},{"revision":"be9a89fb567b632cf8d4661cbf8afd9e","url":"getinfo.webp"},{"revision":"fe986681f41e96631f39f3288b23e538","url":"sysinfo.webp"},{"revision":"4ec902e0b0ce60ffd9dd565c9ddf40a1","url":"send.webp"},{"revision":"81f3c8fc38b876dc2fcfeefaadad1d1b","url":"congrats.webp"},{"revision":"f906318cb87e09a819e5916676caab2e","url":"register.webp"},{"revision":"c633a7500e6f30162bf1cf4ec4e95a6d","url":"later.webp"},{"revision":"d149d5709ac00fd5e2967ab4f3d74886","url":"comic.pdf"}]); const gameFiles = [ "/LEGO/Scripts/CREDITS.SI", "/LEGO/Scripts/INTRO.SI", "/LEGO/Scripts/NOCD.SI", "/LEGO/Scripts/SNDANIM.SI",