Adds the MeshCore web client to the Supply Depot catalog (host port 8500),
alongside the existing Meshtastic apps. Uses aXistem's prebuilt image of Liam
Cottle's MeshCore client (MeshCore is a sibling LoRa mesh project to Meshtastic).
The image is stock nginx serving a static Flutter build over HTTP, but the
client reaches radios via Web Bluetooth / Web Serial, which browsers only allow
from a secure (HTTPS) context. So we serve it over HTTPS: a new preinstall hook
generates a self-signed cert + a small SSL nginx config into storage/meshcore-web,
both bind-mounted into the container (the config over the image's default.conf),
publishing 443. Same one-time browser-warning approach as Vaultwarden, whose
openssl cert generation is refactored into a shared _ensureSelfSignedCert helper.
Also adds a NOMAD-specific docs section + Manage>Docs anchor, and registers the
IconAntenna icon. Meshtastic Web left unchanged.
Validated on NOMAD3 (v1.33.0-rc.1): the image + SSL config + self-signed cert
serves the MeshCore Flutter app over HTTPS 200 with working SPA fallback.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two related fixes surfaced by armandoescalante in #915 when clicking a
Content Explorer category card (e.g. Medicine) on v1.32.0-rc.6:
1. TierSelectionModal placed a useMemo for freeBytes *after* the
`if (!category) return null` early return (introduced in PR #901's
guardrail integration). When `category` transitioned from null to
non-null on first open, React saw a different hook count between
renders and crashed the entire component tree with "Rendered more
hooks than during the previous render", blanking the modal. Moved
the freeBytes useMemo above the early return so hook order is
constant.
2. `IconLibrary` was used as the icon prop on the Manage Custom
Libraries button in remote-explorer.tsx but never registered in
the DynamicIcon allowlist at admin/inertia/lib/icons.ts. Added it
to both the import block and the icons map so the warning stops
firing and the icon renders.
Closes#915.