Skip to content

wireguard: fix wizard Download button unusable behind wait overlay - #149

Merged
ispyisail merged 2 commits into
masterfrom
fix/wizard-download-overlay
Jul 31, 2026
Merged

wireguard: fix wizard Download button unusable behind wait overlay#149
ispyisail merged 2 commits into
masterfrom
fix/wizard-download-overlay

Conversation

@ispyisail

@ispyisail ispyisail commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • Found while building the vnet phase 52/54 regression tests for the wizards (PR wireguard: add a Remote Access Setup Wizard #146/wireguard: add Guest Party Mode #148): step 3's / the guest party done panel's Download Config File button rendered under setControlsEnabled(false)'s wait overlay, which stays up until saveChanges()'s own 5-second-later auto-reload — the overlay blocked every click for the whole window, and the reload then wiped the wizard modal out. Confirmed live with a real browser: the button was never actually clickable.
  • saveChanges() now takes an optional completion callback (every other caller passes nothing, unaffected); the wizards' step3/done/ended handlers are passed as that callback instead of being called unconditionally right after saveChanges() returns, and those handlers clear the overlay themselves once the real backend commit has landed.
  • This also closes a second, subtler race: showing the button immediately (rather than once the backend commit lands) let a fast Download click's own run_commands.sh call overlap saveChanges()'s still in-flight one, both serialized behind the same server-side lock, occasionally producing a 0-byte config download.
  • Follow-up commit: the overlay fix alone wasn't sufficient — saveChanges()'s 5-second auto-reload timer keeps running regardless of the callback, so a user who takes longer than ~5s to finish interacting with the wizard (confirmed live with Guest Party Mode's add-a-second-guest flow) still gets the modal wiped out mid-interaction. saveChanges() now takes a deferReload flag; the three wizard call sites set it and fire the reload themselves only when their own Done button is clicked, not on a fixed timer. Also fixed guestPartyEnd()'s completion callback, which was missing the same setControlsEnabled(true) call the other two handlers already had.

Test plan

  • node --check on the modified file
  • Full tests/wireguard/*.test.js jsdom suite: 83/83 green
  • Live-verified against a real browser (Playwright) + real vnet router: both wizards' Download buttons clickable immediately and reliably, correct config content, multi-step flows (Guest Party's Add Another, End) all complete without the modal being wiped out
  • New vnet phases 52 and 54 (gargoyle-tools repo) exercise both wizards end-to-end, each run clean twice in a row

ispyisail added 2 commits July 31, 2026 09:18
wizardShowStep3()/guestPartyShowDone() rendered a real Download button
under the setControlsEnabled(false) wait overlay saveChanges() leaves up
until its own 5-second-later auto-reload -- confirmed live that the
overlay blocked every click for the whole window, and the reload then
destroyed the modal before a user ever got a working click in.

saveChanges() now takes an optional completion callback; the wizards
pass their step3/done/ended handlers as that callback instead of calling
them unconditionally right after saveChanges() returns, and those
handlers clear the overlay themselves once the real backend commit has
landed. This also closes a second race where a fast Download click could
overlap saveChanges()'s own still-in-flight run_commands.sh call under
the same server-side lock, occasionally producing a 0-byte download.
The overlay fix alone wasn't enough: saveChanges()'s own 5-second
auto-reload timer keeps ticking in the background regardless of the
callback, so a user who takes more than ~5s to click a wizard's Download
button (confirmed live with Guest Party Mode, whose add-a-second-guest
flow routinely takes longer) still gets the modal wiped out from under
them mid-interaction.

saveChanges() now takes a deferReload flag; the three wizard call sites
set it and take over the reload themselves, firing it only when their
own Done button is actually clicked. guestPartyEnd()'s completion
callback was also missing the setControlsEnabled(true) call the other
two already had, for the same overlay-blocking reason.
@ispyisail
ispyisail merged commit cd3c8fe into master Jul 31, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant