The advanced Storage step offered /mnt/disk/apps/libreportal-system as the
default home for LibrePortal's own tree. A registered location's path is where
APP DATA goes and is usually a subdirectory of the drive, so deriving anything
else from it nests that thing inside the app data — LibrePortal's own files
buried under it, on a path that reads as a mistake because it is one.
Both defaults now come off the location's mount point, which meant adding
"mount" to each entry in the storage feed; only the system block carried one.
LibrePortal /mnt/disk/apps/libreportal-system
-> /mnt/disk/libreportal-system
New apps, unregistered drive /mnt/disk
-> /mnt/disk/libreportal-apps
New apps, registered location unchanged — it exists and may hold data, and
proposing a different directory on the same
drive would strand it
Names follow the layout the rest of the product uses (libreportal-system,
libreportal-containers, libreportal-backups) rather than a bare "apps", so a
drive shared with anything else stays legible.
collectStorage() no longer registers the drive picked for LibrePortal. A
storage location is somewhere app data lives; the system tree is not app data
and relocate creates that directory itself as root. Picking a drive there was
producing a location nobody asked for, on a mount chosen for something else.
Also in this change, from the Backup step:
- The backend-specific fields are boxed under their own heading with a note,
so choosing SFTP reveals "the SFTP part" rather than three more loose rows.
- Fields had no vertical spacing. .setup-step gives its DIRECT children a
16px gap, which is where every other step's fields get theirs; these sit a
level deeper inside a .setup-section and inherited none of it, so each
input ran into the next field's label.
- Two field icons carried U+FE0F. Those codepoints have a text form and the
selector only requests the emoji one, so they sat on a different baseline
to the plain emoji beside them — the box measured perfectly centred while
the glyph did not look it.
- ?mode=restore&type=sftp makes the restore branch reachable by URL. Getting
there previously took a click and a change event, so every screenshot and
test had to drive the page before it could look at it.
Two test bugs fixed while doing it: a duplicate `const visible` in one scope
(a parse error, so the whole eval silently returned nothing), and a stub that
covered the POST but not the poll, leaving a 60s loop running that kept the
page from ever going network-idle.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>