From 5ab2cc4c63fcd173826a3e13d3f9ce1c5d476efc Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Sat, 21 Mar 2026 20:08:40 +0100 Subject: [PATCH] Fix bug when going back to NickelMenu step w/ removal --- web/src/js/app.js | 37 ++++++++++++++++++++++--------------- web/src/js/strings.js | 2 +- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/web/src/js/app.js b/web/src/js/app.js index cc6b1b0..bd4bd6f 100644 --- a/web/src/js/app.js +++ b/web/src/js/app.js @@ -402,6 +402,7 @@ import JSZip from 'jszip'; // --- Step 2: Mode selection --- function goToModeSelection() { + resetNickelMenuState(); // In auto mode, disable custom patches if firmware or download URL isn't available const patchesRadio = $q('input[value="patches"]', stepMode); const patchesCard = patchesRadio.closest('.mode-card'); @@ -444,7 +445,7 @@ import JSZip from 'jszip'; if (selectedMode === 'nickelmenu') { setNavLabels(TL.NAV_NICKELMENU); - goToNickelMenuConfig(); + await goToNickelMenuConfig(); } else if (manualMode && !patchesLoaded) { // Manual mode: need version/model selection before patches setNavLabels(TL.NAV_PATCHES); @@ -531,9 +532,6 @@ import JSZip from 'jszip'; const removeRadio = $q('input[value="remove"]', removeOption); const removeDesc = $('nm-remove-desc'); - detectedUninstallFeatures = []; - nmUninstallOptions.hidden = true; - if (!manualMode && device.directoryHandle) { try { const addsDir = await device.directoryHandle.getDirectoryHandle('.adds'); @@ -543,17 +541,19 @@ import JSZip from 'jszip'; removeOption.classList.remove('nm-option-disabled'); removeDesc.textContent = TL.STATUS.NM_REMOVAL_HINT; - // Detect which removable features are installed on the device - for (const feature of ALL_FEATURES) { - if (!feature.uninstall) continue; - for (const detectPath of feature.uninstall.detect) { - if (await device.pathExists(detectPath)) { - detectedUninstallFeatures.push(feature); - break; + if (detectedUninstallFeatures.length === 0) { + // Detect which removable features are installed on the device + for (const feature of ALL_FEATURES) { + if (!feature.uninstall) continue; + for (const detectPath of feature.uninstall.detect) { + if (await device.pathExists(detectPath)) { + detectedUninstallFeatures.push(feature); + break; + } } } + renderUninstallCheckboxes(); } - renderUninstallCheckboxes(); return; } catch { // .adds/nm not found @@ -601,6 +601,12 @@ import JSZip from 'jszip'; } } + function resetNickelMenuState() { + detectedUninstallFeatures = []; + nmUninstallOptions.hidden = true; + nmUninstallOptions.innerHTML = ''; + } + function getSelectedUninstallFeatures() { return detectedUninstallFeatures.filter(f => { const cb = $q(`input[name="nm-uninstall-${f.id}"]`); @@ -617,7 +623,8 @@ import JSZip from 'jszip'; }); } - function goToNickelMenuConfig() { + async function goToNickelMenuConfig() { + await checkNickelMenuInstalled(); renderFeatureCheckboxes(); const currentOption = $q('input[name="nm-option"]:checked', stepNickelMenu); nmConfigOptions.hidden = !currentOption || currentOption.value !== 'preset'; @@ -694,8 +701,8 @@ import JSZip from 'jszip'; showStep(stepNmReview); } - btnNmReviewBack.addEventListener('click', () => { - goToNickelMenuConfig(); + btnNmReviewBack.addEventListener('click', async () => { + await goToNickelMenuConfig(); }); async function executeNmInstall(writeToDevice) { diff --git a/web/src/js/strings.js b/web/src/js/strings.js index 18788c6..0d81c4f 100644 --- a/web/src/js/strings.js +++ b/web/src/js/strings.js @@ -22,7 +22,7 @@ export const TL = { NM_WILL_BE_REMOVED: 'NickelMenu will be updated and marked for removal. It will uninstall itself when your Kobo reboots.', NM_WILL_BE_INSTALLED: 'The following will be installed on your Kobo:', NM_NICKEL_ROOT_TGZ: 'NickelMenu (KoboRoot.tgz)', - NM_REMOVAL_HINT: 'Removes NickelMenu from your device. You must restart your Kobo to complete the uninstall!', + NM_REMOVAL_HINT: 'Removes NickelMenu from your device. Your device will restart automatically.', NM_REMOVAL_DISABLED: 'Removes NickelMenu from your device. Only available when a Kobo with NickelMenu installed is connected.', PATCH_COUNT_ZERO: 'No patches selected \u2014 continuing will restore the original unpatched software.', PATCH_COUNT_ONE: '1 patch selected.',