From c83abc9e9c86920c28d6721cd0618fb6fdd4dc37 Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Wed, 25 Mar 2026 14:18:28 +0100 Subject: [PATCH] Restructured JS files --- web/build.mjs | 10 +- web/eslint.config.mjs | 2 +- web/src/js/app.js | 12 +- web/src/js/dom.js | 53 ++++++++ web/src/js/{ => flows}/nickelmenu-flow.js | 123 +++++------------- web/src/js/{ => flows}/patches-flow.js | 17 +-- web/src/js/{ => services}/kobo-device.js | 0 .../js/{ => services}/kobo-software-urls.js | 4 +- web/src/js/{ => services}/patch-runner.js | 2 +- web/src/js/{ => ui}/patch-ui.js | 8 +- web/src/js/{ => workers}/patch-worker.js | 2 +- web/src/nickelmenu/features/helpers.js | 23 ++++ .../nickelmenu/features/hide-notices/index.js | 11 +- .../features/hide-recommendations/index.js | 11 +- web/src/nickelmenu/features/koreader/index.js | 10 +- .../features/simplify-tabs/index.js | 11 +- web/src/nickelmenu/installer.js | 7 +- 17 files changed, 147 insertions(+), 159 deletions(-) rename web/src/js/{ => flows}/nickelmenu-flow.js (78%) rename web/src/js/{ => flows}/patches-flow.js (96%) rename web/src/js/{ => services}/kobo-device.js (100%) rename web/src/js/{ => services}/kobo-software-urls.js (90%) rename web/src/js/{ => services}/patch-runner.js (96%) rename web/src/js/{ => ui}/patch-ui.js (98%) rename web/src/js/{ => workers}/patch-worker.js (97%) create mode 100644 web/src/nickelmenu/features/helpers.js diff --git a/web/build.mjs b/web/build.mjs index 5bd3985..4c1007c 100644 --- a/web/build.mjs +++ b/web/build.mjs @@ -60,17 +60,17 @@ async function build() { logLevel: 'warning', }); - // Copy worker files from src/js/ (not bundled, served separately) - mkdirSync(join(distDir, 'js'), { recursive: true }); + // Copy worker files from src/js/workers/ (not bundled, served separately) + mkdirSync(join(distDir, 'js', 'workers'), { recursive: true }); // Copy wasm_exec.js as-is const wasmExecSrc = join(srcDir, 'js', 'wasm_exec.js'); if (existsSync(wasmExecSrc)) { - cpSync(wasmExecSrc, join(distDir, 'js', 'wasm_exec.js')); + cpSync(wasmExecSrc, join(distDir, 'js', 'workers', 'wasm_exec.js')); } // Copy patch-worker.js with WASM hash injected - const workerSrc = join(srcDir, 'js', 'patch-worker.js'); + const workerSrc = join(srcDir, 'js', 'workers', 'patch-worker.js'); if (existsSync(workerSrc)) { let workerContent = readFileSync(workerSrc, 'utf-8'); const wasmFile = join(distDir, 'wasm', 'kobopatch.wasm'); @@ -81,7 +81,7 @@ async function build() { `kobopatch.wasm?h=${wasmHash}'` ); } - writeFileSync(join(distDir, 'js', 'patch-worker.js'), workerContent); + writeFileSync(join(distDir, 'js', 'workers', 'patch-worker.js'), workerContent); } // Get git version string diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index 86676a1..35fe33d 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -38,7 +38,7 @@ export default [ }, { // Worker script uses importScripts, self, Go, globalThis, WebAssembly - files: ['src/js/patch-worker.js'], + files: ['src/js/workers/patch-worker.js'], languageOptions: { globals: { self: 'readonly', diff --git a/web/src/js/app.js b/web/src/js/app.js index 5b95133..7f2a53f 100644 --- a/web/src/js/app.js +++ b/web/src/js/app.js @@ -18,17 +18,17 @@ * `state.showError()` when they need to cross module boundaries. */ -import { KoboDevice } from './kobo-device.js'; -import { loadSoftwareUrls, getSoftwareUrl, getDevicesForVersion } from './kobo-software-urls.js'; -import { PatchUI, scanAvailablePatches } from './patch-ui.js'; -import { KoboPatchRunner } from './patch-runner.js'; +import { KoboDevice } from './services/kobo-device.js'; +import { loadSoftwareUrls, getSoftwareUrl, getDevicesForVersion } from './services/kobo-software-urls.js'; +import { PatchUI, scanAvailablePatches } from './ui/patch-ui.js'; +import { KoboPatchRunner } from './services/patch-runner.js'; import { NickelMenuInstaller, ALL_FEATURES } from '../nickelmenu/installer.js'; import { TL } from './strings.js'; import { isEnabled as analyticsEnabled, track } from './analytics.js'; import { $, $q, populateSelect } from './dom.js'; import { showStep, setNavLabels, setNavStep, hideNav, showNav, stepHistory, setupCardRadios } from './nav.js'; -import { initNickelMenu } from './nickelmenu-flow.js'; -import { initPatchesFlow } from './patches-flow.js'; +import { initNickelMenu } from './flows/nickelmenu-flow.js'; +import { initPatchesFlow } from './flows/patches-flow.js'; // ============================================================================= // Shared state diff --git a/web/src/js/dom.js b/web/src/js/dom.js index 0f6706d..34c7248 100644 --- a/web/src/js/dom.js +++ b/web/src/js/dom.js @@ -44,6 +44,59 @@ export function populateSelect(selectEl, placeholder, items) { } } +/** + * Render a list of checkbox items into a container. + * @param {HTMLElement} container + * @param {Array<{name: string, title: string, description: string, checked: boolean, disabled?: boolean}>} items + */ +export function renderNmCheckboxList(container, items) { + container.innerHTML = ''; + for (const item of items) { + const label = document.createElement('label'); + label.className = 'nm-config-item'; + + const input = document.createElement('input'); + input.type = 'checkbox'; + input.name = item.name; + input.checked = item.checked; + if (item.disabled) input.disabled = true; + + const textDiv = document.createElement('div'); + textDiv.className = 'nm-config-text'; + + const titleSpan = document.createElement('span'); + titleSpan.className = 'nm-config-title'; + titleSpan.textContent = item.title; + + const descSpan = document.createElement('span'); + descSpan.className = 'nm-config-desc'; + descSpan.textContent = item.description; + + textDiv.appendChild(titleSpan); + textDiv.appendChild(descSpan); + label.appendChild(input); + label.appendChild(textDiv); + container.appendChild(label); + } +} + +/** Populate a