De nieuwe widget vond meteen een fout, en die zat in de widget zelf

De Status-widget meldde "Not answering" met Errno 111 op een gateway die gewoon
werkte. Die foutmelding was het bewijs: geweigerd betekent dat de naam oploste,
alleen niet naar ons. GATE_TLS_HOST stond op de servicenaam "server", en dat is
een naam die meer apps op een Umbrel gebruiken; op een gedeeld netwerk is het
dus een gok wie je krijgt. Nu de volledige containernaam, precies de vorm die
umbrelOS van APP_HOST verlangt en die twee regels hoger in dezelfde compose al
stond.

Wat dit zegt over de aanname van gisteren: er stond dat dit "dezelfde weg is die
nginx andersom gebruikt". Dat klopte voor de richting maar niet voor de naam, en
het was opgeschreven als redenering in plaats van als meting.

De rest zijn bijstellingen van de gebruiker na het bekijken van 0.0.17. Het menu
is drie kale punten met een accent bij hover in plaats van een knop, de eerste
regel heet Settings zonder de certificaatnaam erachter, de dialoog opent in het
midden in plaats van linksboven, de widgets zijn hoger met hun waarde langs de
onderrand, reactietijd en blokhoogte zijn omgedraaid zodat de reactietijd naast
de server staat waar hij over gaat, en het log is half zo hoog.

De manifest-toets ving onderweg een echte fout: bij het herschrijven van de
release notes was de sleutel releaseNotes zelf weggeknipt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Harmen
2026-08-27 16:04:13 +02:00
co-authored by Claude Opus 5
parent be91125cce
commit 498b0fe695
8 changed files with 172 additions and 49 deletions
+33
View File
@@ -8,6 +8,39 @@ Wat er nog moet gebeuren staat **niet** hier maar in de plannen; zie [CONTINUE_H
Een lijst met geplande features op twee plekken loopt uit elkaar, en dan is geen van beide meer te
vertrouwen.
## [0.0.18] - 2026-08-27
### Fixed
- **De zelfcontrole verbond met de verkeerde container.** De Status-widget meldde `Not answering` met
`[Errno 111] Connection refused` op een gateway die gewoon werkte. De fout was veelzeggend: geweigerd
betekent dat de naam wél oploste, alleen niet naar ons. `GATE_TLS_HOST` stond op de servicenaam `server`,
en dat is een naam die meer apps op een Umbrel gebruiken; op een gedeeld netwerk is het dus een gok wie
je krijgt. Nu de volledige containernaam `whatsnext-electrum-gate_server_1`, dezelfde vorm die umbrelOS
van `APP_HOST` verlangt.
Dit was de eerste keer dat de widget zijn nut bewees, en meteen op zichzelf: zonder de foutmelding op de
pagina was dit een stille verkeerde meting geweest.
### Changed
Bijstellingen van de gebruiker na het bekijken van 0.0.17, allemaal op de pagina.
- **Het menu is drie kale punten met een accent bij hover**, geen knop meer. Een rand en een vlak voegden
niets toe naast een kop die verder alleen het merk bevat.
- **De eerste menuregel heet `Settings…`** en herhaalt de naam van het actieve certificaat niet meer; die
stond al als onderregel van de certificaatwidget. De dialoog heet nu ook `Settings`, want anders klik je
op het ene woord en kom je op het andere uit.
- **De dialoog opent in het midden van het scherm** in plaats van linksboven. Niet op de standaardopmaak
van de browser vertrouwen: die plaatst een `dialog` ten opzichte van zijn dichtstbijzijnde geplaatste
voorouder, en deze staat in het raster van de pagina.
- **De widget `Gateway` heet `Status`.**
- **De widgets zijn iets hoger, met hun waarde langs de onderrand.** Zonder een minimumhoogte bepaalde de
hoogste widget de rij, en dan stond de titel vrijwel tegen de waarde aan.
- **Reactietijd en blokhoogte zijn omgedraaid**, zodat de reactietijd naast de server staat waar hij over
gaat. Dat is meteen de stapelvolgorde op een smal scherm; er staat nergens een `order` in de CSS.
- **Het activiteitenlog is half zo hoog** (30vh in plaats van 60vh).
## [0.0.17] - 2026-08-27
### Changed
+1 -1
View File
@@ -23,7 +23,7 @@
| Plan | App | Volgende stap | Status |
|-|-|-|-|
| [Webinterface](Plannen/Actief/005-Webinterface/TAKEN.md) | Gate | **Fase 6 is gebouwd en uitgerold als 0.0.17 (27-08-2026), maar in geen enkele browser gezien.** Nakijken op een breed scherm én op een telefoon is nu de volgende stap: de bovenste rij gaat van vijf naar drie naar twee kolommen, en de certificaatdialoog is nieuw. Daarna resteert alleen nog het uploaden op het niet-gelukkige pad | 🔶 |
| [Webinterface](Plannen/Actief/005-Webinterface/TAKEN.md) | Gate | **Fase 6 draait en is goedgekeurd op een breed scherm; de bijstellingen zitten in 0.0.18.** Nog te doen: nakijken op een telefoon (de stap van vijf naar drie naar twee kolommen, en de dialoog op smal), en het uploaden op het niet-gelukkige pad. Allebei bij de gebruiker | 🔶 |
| [Umbrelapp](Plannen/Actief/008-Umbrelapp/TAKEN.md) | Relay | **Hij draait sinds 25-08-2026, maar kan in de kern niet werken.** Uit de broncode van Suite: bij een eigen relay-URL registreert de cliënt geen eigenaar, terwijl Trezor's relay iedereen zonder limietenrij weigert. Volgende stap is de kále Evolu-relay proberen (`docker.io/evoluhq/relay:latest`, één container, gepubliceerde image) en waarschijnlijk daarnaartoe verbouwen. Zie open punt 6 | 🔶 |
| [Proefopstelling](Plannen/Actief/007-Proefopstelling/TAKEN.md) | Relay | **Eerst beslissen of dit plan nog bestaansrecht heeft.** Fase 1 is af, maar fase 2 en 3 zijn ingehaald: het pakket draait al op de Umbrel, dus een lokale opstelling ernaast meet minder en kost meer. Wat overblijft zijn twee vragen die al als blokkade in **Umbrelapp** staan, en die horen op één plek | 🔶 |
@@ -1,5 +1,30 @@
# Voortgang - Webinterface
## 27-08-2026 - de nieuwe widget vond meteen een fout, en die zat in de widget zelf
De gebruiker heeft 0.0.17 bekeken: het werkt, met een lijst bijstellingen. Verwerkt in 0.0.18. De
belangrijkste is geen smaakkwestie maar een echte fout: **de Status-widget meldde `Not answering` met
`[Errno 111] Connection refused` op een gateway die gewoon werkte.**
Die foutmelding was het bewijs. Geweigerd betekent dat de naam oploste, alleen niet naar ons.
`GATE_TLS_HOST` stond op de servicenaam `server`, en dat is een naam die meer apps op een Umbrel
gebruiken; op een gedeeld netwerk is het dan een gok wie je krijgt. Nu de volledige containernaam, precies
de vorm die umbrelOS van `APP_HOST` verlangt en die er in dezelfde compose al twee regels boven stond.
Wat dit zegt over de aanname van gisteren: er stond dat de weg naar `server` "dezelfde weg is die nginx
andersom gebruikt". Dat klopte voor de richting maar niet voor de naam, en het was opgeschreven als
redenering in plaats van als meting.
De rest is opmaak: het menu is drie kale punten met hover-accent in plaats van een knop, de eerste
menuregel heet `Settings…` zonder de certificaatnaam erachter, de dialoog opent in het midden in plaats
van linksboven, de widgets zijn hoger met hun waarde onderin, reactietijd en blokhoogte zijn omgedraaid,
en het log is half zo hoog.
**Geraakt:** `index.html.template`, `docker-compose.yml`, `agent.py.template` (alleen commentaar),
`umbrel-app.yml` (0.0.18), dit plan, de changelog. **Tests:** 39, 32, 54 en 22 goed, 0 fout. De
manifest-toets ving onderweg een echte fout: bij het herschrijven van de release notes was de sleutel
`releaseNotes` zelf weggeknipt.
## 27-08-2026 - de tweede indeling gebouwd, en er ging meer weg dan erbij kwam
Fase 6 in één keer gebouwd, uitgeleverd als 0.0.17: vijf widgets op de bovenste rij, de certificaatkeuze
+11 -4
View File
@@ -266,10 +266,17 @@ de vijfde widget; de rest is de pagina verbouwen om wat er dan staat.
- [x] Twee kopieerknoppen, met de wallets gegroepeerd onder de vorm die ze vragen
- [x] Opgeruimd wat vervalt: de hoogtekoppeling van log en certificaatkader, het meerekken van de tegels,
en `.col-5` en `.col-7` uit de CSS
- [ ] **Na afloop op mobiel nakijken, net als bij 0.0.10.** Niets van deze indeling is in een browser
gezien, en dat is bij een verbouwing van deze omvang de helft van de verificatie. Let vooral op de
stap van vijf naar drie naar twee kolommen, en op de dialoog op een smal scherm.
**Eigenaar: gebruiker**
- [x] **Op een breed scherm nagekeken (27-08-2026). Werkt goed volgens de gebruiker**, met een lijst
bijstellingen die in 0.0.18 verwerkt is: menu zonder knoplook, `Settings…` zonder certificaatnaam,
dialoog in het midden, hogere widgets met de waarde onderin, reactietijd en blokhoogte omgedraaid,
log half zo hoog, en de widget heet nu `Status`
- [x] **En de widget vond meteen een echte fout.** `Not answering` met `[Errno 111] Connection refused` op
een werkende gateway: `GATE_TLS_HOST` stond op de servicenaam `server`, die op een Umbrel met meer
apps niet van ons alleen is. Nu de volledige containernaam. Verholpen in 0.0.18
- [ ] **Nog op een telefoon nakijken**, net als bij 0.0.10. Let op de stap van vijf naar drie naar twee
kolommen en op de dialoog op een smal scherm. **Eigenaar: gebruiker**
## Geblokkeerd / wacht op
+8 -4
View File
@@ -50,10 +50,14 @@ TLS_PORT = int(os.environ.get("GATE_TLS_PORT", "50022"))
# De zelfcontrole: de agent verbindt met de eigen TLS-poort. Zie het plan
# Webinterface, OPEN.md punt 5.
#
# GATE_TLS_HOST is de nginx-container hiernaast. Servicenamen resolven binnen het
# compose-netwerk; dat is dezelfde weg die nginx andersom gebruikt om bij deze
# agent te komen. Niet localhost: dat is een andere container en dus een andere
# netwerk-namespace.
# GATE_TLS_HOST is de nginx-container hiernaast. Niet localhost: dat is een andere
# container en dus een andere netwerk-namespace.
#
# De compose zet hier de volledige containernaam neer en niet de servicenaam. Die
# stond er eerst, en op het apparaat leverde dat `[Errno 111] Connection refused`
# op: de naam loste op, maar naar een andere container. Zie de toelichting in
# docker-compose.yml. De standaard hieronder is alleen de terugval voor een
# opstelling zonder die variabele.
#
# Waarom deze controle niet elke ronde draait: elke verbinding met poort 50022 is
# voor nginx een gewone sessie en levert dus een regel in het activiteitenlog op.
+11 -4
View File
@@ -29,10 +29,17 @@ services:
GATE_ELECTRUM_PORT: ${APP_ELECTRS_NODE_PORT}
GATE_TLS_PORT: "50022"
# De zelfcontrole: de agent verbindt met de TLS-poort van de server
# hieronder en maakt de handdruk af. De servicenaam resolveert binnen het
# compose-netwerk, en dat is dezelfde weg die nginx andersom gebruikt met
# zijn proxy_pass naar 'agent'. Niet localhost: dat is een andere container.
GATE_TLS_HOST: server
# hieronder en maakt de handdruk af. Niet localhost: dat is een andere
# container en dus een andere netwerk-namespace.
#
# De volledige containernaam en niet de servicenaam 'server'. Dat stond er
# eerst, en op het apparaat gaf het `[Errno 111] Connection refused`
# (27-08-2026). Die fout is veelzeggend: geweigerd betekent dat de naam wél
# oploste, alleen niet naar ons. 'server' is een naam die meer apps op deze
# machine gebruiken, en op een gedeeld netwerk is het dus een gok wie je
# krijgt. De vorm <app-id>_<service>_1 is uniek per app; het is niet toevallig
# dezelfde vorm die umbrelOS hierboven van APP_HOST verlangt.
GATE_TLS_HOST: whatsnext-electrum-gate_server_1
# Niet elke ronde meten, want elke meting is voor nginx een gewone sessie
# en levert dus een regel in het activiteitenlog op. Vijf minuten is vaak
# genoeg voor een waarde die zelden verandert; na een certificaatwissel
+68 -24
View File
@@ -207,8 +207,14 @@ body {
@media (max-width: 560px) { .row1 { grid-template-columns: 1fr; } }
/* De widgets zetten hun waarde onderaan, zodat de vijf getallen op één lijn
staan ook als de ene titel over twee regels valt en de andere niet. */
.row1 .card { display: flex; flex-direction: column; }
staan ook als de ene titel over twee regels valt en de andere niet.
De min-height is er op verzoek van de gebruiker (27-08-2026): zonder die maat
bepaalt de hoogste widget de rij, en dat leverde vijf krappe blokjes op waarin
de titel vrijwel tegen de waarde aan stond. Met wat meer hoogte krijgt de
waarde de ruimte om echt onderin te staan, en dát is wat margin-top: auto
hierboven doet zodra er hoogte over is. */
.row1 .card { display: flex; flex-direction: column; min-height: 10.5rem; }
.row1 .stat-body { margin-top: auto; }
/* De twee clientlijsten naast elkaar zodra er ruimte is; het zijn twee losse
@@ -349,7 +355,10 @@ body {
flex: 0 0 auto;
/* Er passen vier regels in; dat is de bodem voor een leeg of net gestart log. */
min-height: 110px;
max-height: 60vh;
/* De helft van wat het was, op verzoek van de gebruiker (27-08-2026). Met 60vh
vulde het log het scherm terwijl er zelden meer dan een handvol regels in
staat; wat er niet in past, scrolt hier toch al. */
max-height: 30vh;
overflow: auto;
overscroll-behavior: contain;
scrollbar-width: thin;
@@ -410,17 +419,32 @@ body {
.menu > summary { list-style: none; cursor: pointer; }
.menu > summary::-webkit-details-marker { display: none; }
.menu > summary::marker { content: ''; }
/* Flink, want drie punten op de gewone knopgrootte van 0,75rem zijn nauwelijks
te zien en al helemaal niet te raken. De letterafstand zet ze uit elkaar,
anders plakken ze in de meeste letterfamilies aan elkaar. De vaste hoogte en
line-height houden de knop even hoog als hij met tekst erin zou zijn. */
/* Geen knoplook, op verzoek van de gebruiker (27-08-2026): alleen de drie punten,
met een accent bij hover. Hier stond de klasse .btn, en die gaf er een rand en
een vlak omheen die niets toevoegden naast een kop met alleen het merk erin.
Flink van formaat, want drie punten op de gewone knopgrootte van 0,75rem zijn
nauwelijks te zien en al helemaal niet te raken. De letterafstand zet ze uit
elkaar, anders plakken ze in de meeste letterfamilies aan elkaar. De padding
blijft: dat is het raakvlak, ook al is er niets omheen te zien. */
.menu-button {
display: inline-flex; align-items: center; justify-content: center;
font-size: 1.4rem;
line-height: 1;
letter-spacing: 0.08em;
padding: 0.3rem 0.7rem 0.5rem;
padding: 0.25rem 0.6rem 0.45rem;
min-height: 2rem;
color: var(--text-sec);
border-radius: var(--radius-sm);
transition: color 0.2s var(--ease-out);
}
.menu-button:hover { color: var(--accent); }
/* Ook accent zolang het menu openstaat, anders lijkt de knop terug te springen
naar rust terwijl het paneel eronder nog open is. */
.menu[open] > .menu-button { color: var(--accent); }
/* Zonder rand is er geen vorm die de standaard focusring volgt, dus die zetten
we zelf; met het toetsenbord moet zichtbaar zijn waar je staat. */
.menu-button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.menu-panel {
position: absolute; right: 0; top: calc(100% + 0.4rem);
z-index: 20; min-width: 15rem;
@@ -445,6 +469,15 @@ body {
geen hoogte van een buur, dus de keuzelijst en het uploadblok kunnen hier
gewoon staan zonder dat er elders leegte ontstaat. */
.sheet {
/* Midden op het scherm, in beide richtingen (27-08-2026: hij kwam linksboven
terecht). Niet op de standaardopmaak van de browser vertrouwen: die zet een
dialog absoluut ten opzichte van zijn dichtstbijzijnde geplaatste voorouder,
en deze staat in het raster van de pagina. Vast plaatsen met inset 0 en
marge auto centreert hem tegen het scherm, ongeacht waar hij in de HTML
staat. */
position: fixed;
inset: 0;
margin: auto;
/* Alleen van belang in de terugvalroute zonder showModal; zie de HTML. */
grid-column: 1 / -1;
width: min(46rem, calc(100vw - 2rem));
@@ -582,11 +615,15 @@ body {
staan op de basislijn en zakken dus naar de onderrand van de knop,
terwijl deze vanzelf op halve hoogte staan. Hetzelfde teken dat elders
op deze pagina de velden in een keuzeregel scheidt. -->
<summary class="btn menu-button" title="Settings" aria-label="Settings">···</summary>
<summary class="menu-button" title="Settings" aria-label="Settings">···</summary>
<div class="menu-panel">
<!-- "Settings…" en niet "Certificates", en zonder de naam van het actieve
certificaat erachter (27-08-2026, gebruiker). Die naam stond al als
onderregel van de certificaatwidget, dus hier was het een derde plek
voor dezelfde waarde. Het beletselteken is de gebruikelijke belofte
dat er een dialoog volgt en niet meteen een handeling. -->
<button class="menu-item" id="menu-certs" type="button">
<span>Certificates</span>
<span class="menu-meta" id="menu-certs-meta"></span>
<span>Settings…</span>
</button>
<!-- De regel toont de huidige stand en niet de handeling. De losse knop
hiervoor deed het andersom, met "Light" terwijl de pagina donker was.
@@ -684,16 +721,11 @@ body {
</div>
</div>
<div class="card">
<div class="card-head">
<h2 class="t-h3">Block height</h2>
</div>
<div class="stat-body">
<div class="stat-val unknown" id="stat-height">unknown</div>
<div class="stat-sub" id="stat-height-sub"></div>
</div>
</div>
<!-- Reactietijd vóór blokhoogte, omgedraaid op verzoek van de gebruiker
(27-08-2026). Hij staat daarmee naast de Electrum-server waar hij over
gaat, en de blokhoogte schuift naar het midden van de rij. Let op: dit is
de leesvolgorde in de HTML en dus ook de stapelvolgorde op een smal
scherm; er staat nergens een order in de CSS die daarvan afwijkt. -->
<div class="card">
<div class="card-head">
<h2 class="t-h3">Backend response</h2>
@@ -704,6 +736,16 @@ body {
</div>
</div>
<div class="card">
<div class="card-head">
<h2 class="t-h3">Block height</h2>
</div>
<div class="stat-body">
<div class="stat-val unknown" id="stat-height">unknown</div>
<div class="stat-sub" id="stat-height-sub"></div>
</div>
</div>
<!-- Het certificaat als getal en niet als kaart. Kiezen, uploaden en de
details zitten sinds 27-08-2026 in de dialoog achter het menu; wat hier
staat is wat je in één oogopslag wilt weten. Het aantal dagen tot
@@ -729,7 +771,7 @@ body {
en niet de weg ernaartoe; de onderregel zegt dat er ook bij. -->
<div class="card">
<div class="card-head">
<h2 class="t-h3">Gateway</h2>
<h2 class="t-h3">Status</h2>
</div>
<div class="stat-body">
<div class="stat-val text unknown" id="self-state">unknown</div>
@@ -752,7 +794,10 @@ body {
staat er in .sheet een grid-column op de volle breedte. -->
<dialog id="cert-dialog" class="sheet">
<form method="dialog" class="sheet-head">
<h2 class="t-h3">Certificates</h2>
<!-- Zelfde woord als de menuregel die hem opent. Stond hier "Certificates"
terwijl je op "Settings…" klikte, en dan lijkt het even of je ergens
anders bent uitgekomen dan je dacht. -->
<h2 class="t-h3">Settings</h2>
<button class="btn" value="close" aria-label="Close">Close</button>
</form>
@@ -1116,7 +1161,6 @@ body {
put('cert-domain', tls.domain);
put('cert-dialog-domain', tls.domain);
put('cert-reload', whenLocal(cert.last_reload));
el('menu-certs-meta').textContent = cert.selected ? (tls.domain || 'in use') : 'none in use';
renderCertAlert(daysLeft);
drawCertChoices(s.certificates, cert.selected, nowSec);
+15 -12
View File
@@ -9,7 +9,7 @@ manifestVersion: 1
id: whatsnext-electrum-gate
category: bitcoin
name: Electrum Gate
version: "0.0.17"
version: "0.0.18"
tagline: Your own node from anywhere, without waiting for Tor
description: >-
The privacy win is already yours: you run the Electrum server. A public one gets asked for
@@ -56,24 +56,27 @@ description: >-
# staan. In 0.0.9 stond er daardoor drie keer "Earlier releases" en twee keer
# dezelfde 0.0.4-regel. De toets let er nu op.
releaseNotes: >-
The dashboard has been rebuilt around five small tiles: your Electrum server, block height, response
time, your certificate, and whether the gateway itself is answering. That last one is the check added
in the previous release, which until now had nowhere to show.
The Status tile was reporting "Not answering" on a gateway that was working fine. The check was
connecting to the wrong container: it asked for "server", and on a machine running several apps that
name is not ours alone. It now uses the full container name, and the tile reports what your wallets
already knew.
Choosing and uploading certificates moved into a dialog behind the menu at the top right, together with
the light and dark setting. Nothing is harder to find: when no certificate is in use, the message at the
top of the page still takes you straight there, and that message is what a fresh install shows.
The activity log now runs the full width of the page. "Setting up your wallet" starts collapsed and is
much shorter. There are only two forms of the same address, so there are two copy buttons instead of one
per wallet, with the wallets listed under the form each of them asks for.
The rest of this release is polish on the new dashboard. The menu is three plain dots that pick up
colour on hover, instead of a button; its first item is now "Settings" and no longer repeats the
certificate name. The dialog opens in the middle of the screen rather than the top left corner. The
tiles are a little taller, with their values sitting along the bottom. Response time and block height
swapped places, so response time sits next to the server it measures. The activity log is half as tall.
Earlier releases:
0.0.17 rebuilt the dashboard around five small tiles, moved choosing and uploading certificates into a
dialog behind the menu at the top right, put the activity log across the full width, and collapsed
"Setting up your wallet" into a much shorter panel with two copy buttons instead of one per wallet.
0.0.16 taught the app to check its own front door: it connects to its own TLS port, completes the
handshake, and compares the certificate it gets back with the one you picked. That catches a
certificate change that never actually took effect, which looks fine from the outside and fails at your