Add more integration tests
All checks were successful
Build and test project / build-and-test (push) Successful in 1m46s
All checks were successful
Build and test project / build-and-test (push) Successful in 1m46s
This commit is contained in:
@@ -308,19 +308,15 @@ h2 {
|
||||
|
||||
/* NickelMenu config checkboxes */
|
||||
.nm-config-options {
|
||||
margin-top: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--border-light);
|
||||
border-radius: 10px;
|
||||
box-shadow: var(--shadow);
|
||||
padding: 0 0.25rem;
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
|
||||
.nm-config-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: flex-start;
|
||||
gap: 0.6rem;
|
||||
padding: 0.4rem 0;
|
||||
padding: 0.5rem 0;
|
||||
font-size: 0.88rem;
|
||||
color: var(--text);
|
||||
cursor: pointer;
|
||||
@@ -332,6 +328,7 @@ h2 {
|
||||
|
||||
.nm-config-item input[type="checkbox"] {
|
||||
flex-shrink: 0;
|
||||
margin-top: 0.15rem;
|
||||
accent-color: var(--primary);
|
||||
}
|
||||
|
||||
@@ -339,8 +336,32 @@ h2 {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.nm-config-item span {
|
||||
.nm-config-text {
|
||||
user-select: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.nm-config-desc {
|
||||
display: block;
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.4;
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
.nm-config-link {
|
||||
display: block;
|
||||
margin-top: 0.75rem;
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
border-top: 1px solid var(--border-light);
|
||||
font-size: 0.8rem;
|
||||
color: var(--primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nm-config-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.nm-option input[type="radio"] {
|
||||
@@ -387,6 +408,12 @@ h2 {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.step-actions-right {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
button {
|
||||
font-size: 0.9rem;
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<svg class="mode-card-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 16 16" fill="currentColor"><path d="m7.792.312-1.533 2.3A.25.25 0 0 0 6.467 3H7.5v7.319a2.5 2.5 0 0 0-.515-.298L5.909 9.56A1.5 1.5 0 0 1 5 8.18v-.266a1.5 1.5 0 1 0-1 0v.266a2.5 2.5 0 0 0 1.515 2.298l1.076.461a1.5 1.5 0 0 1 .888 1.129 2.001 2.001 0 1 0 1.021-.006v-.902a1.5 1.5 0 0 1 .756-1.303l1.484-.848A2.5 2.5 0 0 0 11.995 7h.755a.25.25 0 0 0 .25-.25v-2.5a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25v2.5c0 .138.112.25.25.25h.741a1.5 1.5 0 0 1-.747 1.142L8.76 8.99a2.584 2.584 0 0 0-.26.17V3h1.033a.25.25 0 0 0 .208-.389L8.208.312a.25.25 0 0 0-.416 0Z"/></svg>
|
||||
<div class="mode-card-body">
|
||||
<div class="mode-card-title">Connect my Kobo</div>
|
||||
<div class="mode-card-desc">Connect your Kobo via USB and select its drive. Files will be written directly to the device.</div>
|
||||
<div class="mode-card-desc">Connect your Kobo via USB and select its drive. You will have the option to apply these changes directly, or you can download a ZIP.</div>
|
||||
</div>
|
||||
</button>
|
||||
<button id="btn-manual" class="mode-card mode-card-btn">
|
||||
@@ -144,13 +144,51 @@
|
||||
<section id="step-nickelmenu" class="step" hidden>
|
||||
<p>Choose what to do with your Kobo.</p>
|
||||
<div class="nm-options">
|
||||
<label class="nm-option nm-option-selected">
|
||||
<input type="radio" name="nm-option" value="sample" checked>
|
||||
<label class="nm-option">
|
||||
<input type="radio" name="nm-option" value="sample">
|
||||
<div class="nm-option-body">
|
||||
<div class="nm-option-title">Install NickelMenu and configure</div>
|
||||
<div class="nm-option-desc">Installs NickelMenu with a curated set of menu options.</div>
|
||||
</div>
|
||||
</label>
|
||||
<div id="nm-config-options" class="nm-config-options" hidden>
|
||||
<label class="nm-config-item">
|
||||
<input type="checkbox" name="nm-cfg-menu" checked disabled>
|
||||
<div class="nm-config-text">
|
||||
<span>Set up custom menu</span>
|
||||
<span class="nm-config-desc">Adds menu items for dark mode, screenshots, and more. A new tab will be added in the bottom navigation that is labelled "Tweak".</span>
|
||||
</div>
|
||||
</label>
|
||||
<label class="nm-config-item">
|
||||
<input type="checkbox" name="nm-cfg-fonts" checked>
|
||||
<div class="nm-config-text">
|
||||
<span>Install Readerly fonts</span>
|
||||
<span class="nm-config-desc">Adds the free Readerly fonts, which are visually similar to Bookerly.</span>
|
||||
</div>
|
||||
</label>
|
||||
<label class="nm-config-item">
|
||||
<input type="checkbox" name="nm-cfg-screensaver">
|
||||
<div class="nm-config-text">
|
||||
<span>Install screensaver</span>
|
||||
<span class="nm-config-desc">Replaces the default sleep screen with a custom screensaver image.</span>
|
||||
</div>
|
||||
</label>
|
||||
<label class="nm-config-item">
|
||||
<input type="checkbox" name="nm-cfg-simplify-tabs">
|
||||
<div class="nm-config-text">
|
||||
<span>Hide Notebook & Store tabs</span>
|
||||
<span class="nm-config-desc">This will hide the Notebook and Store tabs from the bottom navigation.</span>
|
||||
</div>
|
||||
</label>
|
||||
<label class="nm-config-item">
|
||||
<input type="checkbox" name="nm-cfg-simplify-home">
|
||||
<div class="nm-config-text">
|
||||
<span>Simpler home screen</span>
|
||||
<span class="nm-config-desc">If you are reading only one book, no recommendations will appear next to your current read, and third row on your homescreen with advertisements for Kobo Plus and the Kobo Store will be hidden.</span>
|
||||
</div>
|
||||
</label>
|
||||
<a href="https://github.com/nicoverbruggen/kobo-config" target="_blank" class="nm-config-link">Learn more about these customisations ›</a>
|
||||
</div>
|
||||
<label class="nm-option">
|
||||
<input type="radio" name="nm-option" value="nickelmenu-only">
|
||||
<div class="nm-option-body">
|
||||
@@ -166,28 +204,6 @@
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div id="nm-config-options" class="nm-config-options" hidden>
|
||||
<label class="nm-config-item">
|
||||
<input type="checkbox" name="nm-cfg-menu" checked disabled>
|
||||
<span>Set up custom menu</span>
|
||||
</label>
|
||||
<label class="nm-config-item">
|
||||
<input type="checkbox" name="nm-cfg-fonts" checked>
|
||||
<span>Install Readerly fonts</span>
|
||||
</label>
|
||||
<label class="nm-config-item">
|
||||
<input type="checkbox" name="nm-cfg-screensaver" checked>
|
||||
<span>Install screensaver</span>
|
||||
</label>
|
||||
<label class="nm-config-item">
|
||||
<input type="checkbox" name="nm-cfg-simplify-tabs">
|
||||
<span>Simplify tab menu</span>
|
||||
</label>
|
||||
<label class="nm-config-item">
|
||||
<input type="checkbox" name="nm-cfg-simplify-home">
|
||||
<span>Simplify homescreen</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="step-actions">
|
||||
<button id="btn-nm-back" class="secondary">‹ Back</button>
|
||||
<button id="btn-nm-next" class="primary">Continue ›</button>
|
||||
@@ -200,8 +216,10 @@
|
||||
<ul id="nm-review-list" class="selected-patches-list"></ul>
|
||||
<div id="nm-review-actions" class="step-actions">
|
||||
<button id="btn-nm-review-back" class="secondary">‹ Back</button>
|
||||
<button id="btn-nm-write" class="primary">Write to Kobo</button>
|
||||
<button id="btn-nm-download" class="secondary">Download ZIP</button>
|
||||
<div class="step-actions-right">
|
||||
<button id="btn-nm-download" class="secondary">Download ZIP</button>
|
||||
<button id="btn-nm-write" class="primary">Write to Kobo</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -226,6 +244,9 @@
|
||||
<ol class="install-steps">
|
||||
<li>Connect your Kobo via USB so it appears as a removable drive.</li>
|
||||
<li>Extract the downloaded ZIP to the <strong>root</strong> of the Kobo drive, preserving the folder structure.</li>
|
||||
<li id="nm-download-conf-step" hidden>Open <strong>.kobo/Kobo/Kobo eReader.conf</strong> in a text editor. Find the <code>[FeatureSettings]</code> section (or add it at the end) and add the following line:<br>
|
||||
<code>ExcludeSyncFolders=(calibre|\.(?!kobo|adobe|calibre).+|([^.][^/]*/)+\..+)</code><br>
|
||||
This prevents the Kobo from removing the custom folders during a sync.</li>
|
||||
<li><strong>Safely eject</strong> the Kobo — do not just unplug the cable.</li>
|
||||
<li>The device will reboot and install NickelMenu automatically.</li>
|
||||
</ol>
|
||||
@@ -340,18 +361,27 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
KoboPatch Web UI is a fully client-side web application for applying custom
|
||||
<a href="https://github.com/pgaskin/kobopatch" target="_blank">kobopatch</a> patches
|
||||
to Kobo e-readers. Nothing is uploaded to a server — everything runs in your browser.
|
||||
KoboPatch Web UI is a fully client-side web application for customising
|
||||
Kobo e-readers. Nothing is uploaded to a server — everything runs in your browser.
|
||||
</p>
|
||||
|
||||
<h3>The patching process</h3>
|
||||
<h3>NickelMenu</h3>
|
||||
<p>
|
||||
<a href="https://pgaskin.net/NickelMenu/" target="_blank">NickelMenu</a> adds custom menu items
|
||||
and tweaks to your Kobo. This tool can install NickelMenu along with an optional curated
|
||||
configuration (custom menus, fonts, screensavers) or remove it. NickelMenu works with
|
||||
most Kobo devices and includes a failsafe that automatically uninstalls itself if
|
||||
something goes wrong.
|
||||
</p>
|
||||
|
||||
<h3>Custom patches</h3>
|
||||
<ol>
|
||||
<li><strong>Device selection</strong> — On Chromium-based browsers (Chrome, Edge), the app can
|
||||
auto-detect your Kobo via the File System Access API when connected over USB.
|
||||
On other browsers, you manually select your model and software version.</li>
|
||||
<li><strong>Patch configuration</strong> — You choose which patches to enable or disable.
|
||||
Patches in the same group are mutually exclusive (radio buttons).
|
||||
<li><strong>Patch configuration</strong> — You choose which
|
||||
<a href="https://github.com/pgaskin/kobopatch" target="_blank">kobopatch</a> patches
|
||||
to enable or disable. Patches in the same group are mutually exclusive.
|
||||
The patches themselves are community-contributed via the
|
||||
<a href="https://www.mobileread.com/forums/forumdisplay.php?f=247" target="_blank">MobileRead forums</a>.</li>
|
||||
<li><strong>Build</strong> — The correct software update is downloaded directly from Kobo's servers
|
||||
@@ -374,10 +404,11 @@
|
||||
|
||||
<h3>Safety</h3>
|
||||
<p>
|
||||
Each patched binary is validated before being included in the output: ELF magic bytes,
|
||||
NickelMenu includes a built-in failsafe mechanism. For custom patches, each patched binary
|
||||
is validated before being included in the output: ELF magic bytes,
|
||||
32-bit ARM architecture, file size (must match the original), and archive integrity are
|
||||
all checked. If anything looks wrong, the build fails with an error. That said, patching
|
||||
modifies system files, so you should know how to
|
||||
all checked. If anything looks wrong, the build fails with an error. That said, both
|
||||
NickelMenu and custom patches modify system files, so you should know how to
|
||||
<a href="https://help.kobo.com/hc/en-us/articles/360017605314" target="_blank">manually reset your Kobo</a>
|
||||
if needed.
|
||||
</p>
|
||||
|
||||
@@ -401,10 +401,11 @@
|
||||
// --- Step 2b: NickelMenu configuration ---
|
||||
const nmConfigOptions = $('nm-config-options');
|
||||
|
||||
// Show/hide config checkboxes based on radio selection
|
||||
// Show/hide config checkboxes based on radio selection, enable Continue
|
||||
for (const radio of $qa('input[name="nm-option"]', stepNickelMenu)) {
|
||||
radio.addEventListener('change', () => {
|
||||
nmConfigOptions.hidden = radio.value !== 'sample' || !radio.checked;
|
||||
btnNmNext.disabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -447,9 +448,9 @@
|
||||
|
||||
function goToNickelMenuConfig() {
|
||||
checkNickelMenuInstalled();
|
||||
// Reset config visibility based on current selection
|
||||
const currentOption = $q('input[name="nm-option"]:checked', stepNickelMenu);
|
||||
nmConfigOptions.hidden = !currentOption || currentOption.value !== 'sample';
|
||||
btnNmNext.disabled = !currentOption;
|
||||
setNavStep(3);
|
||||
showStep(stepNickelMenu);
|
||||
}
|
||||
@@ -478,7 +479,7 @@
|
||||
list.innerHTML = '';
|
||||
|
||||
if (nickelMenuOption === 'remove') {
|
||||
summary.textContent = 'NickelMenu will be removed from your device.';
|
||||
summary.textContent = 'NickelMenu will be updated and marked for removal. It will uninstall itself when your Kobo reboots.';
|
||||
btnNmWrite.hidden = manualMode;
|
||||
btnNmWrite.textContent = 'Remove from Kobo';
|
||||
btnNmDownload.hidden = true;
|
||||
@@ -531,7 +532,11 @@
|
||||
|
||||
try {
|
||||
if (nickelMenuOption === 'remove') {
|
||||
nmProgress.textContent = 'Removing NickelMenu...';
|
||||
await nmInstaller.loadAssets((msg) => { nmProgress.textContent = msg; });
|
||||
nmProgress.textContent = 'Writing KoboRoot.tgz...';
|
||||
const tgz = await nmInstaller.getKoboRootTgz();
|
||||
await device.writeFile(['.kobo', 'KoboRoot.tgz'], tgz);
|
||||
nmProgress.textContent = 'Marking NickelMenu for removal...';
|
||||
await device.writeFile(['.adds', 'nm', 'uninstall'], new Uint8Array(0));
|
||||
showNmDone('remove');
|
||||
return;
|
||||
@@ -574,6 +579,8 @@
|
||||
nmDoneStatus.textContent = 'Your NickelMenu package is ready to download.';
|
||||
triggerDownload(resultNmZip, 'NickelMenu-install.zip', 'application/zip');
|
||||
$('nm-download-instructions').hidden = false;
|
||||
// Show eReader.conf step only when sample config is included
|
||||
$('nm-download-conf-step').hidden = nickelMenuOption !== 'sample';
|
||||
}
|
||||
|
||||
setNavStep(5);
|
||||
|
||||
Reference in New Issue
Block a user