feat(join): a route whose first step the join can take is not blocked - #351
Merged
Merged
Conversation
Applying for vetting without a persona was greyed out with "create one under My Identity". On a community that vets, that made the one route the community is actually telling you about look like the one you could not use — and made the way forward look like configuration work to go and do somewhere else, which is exactly what a join flow should absorb. The distinction the code was missing is who has to supply the missing thing. A persona is something OpenVTC can make for you, so a route that needs one is a route you can take; it just begins a step earlier. An invitation is a credential somebody else has to have issued you, so holding none really is a shut door — there is no step that would produce one. `RouteState` names the three cases (`Ready`, `FirstStep`, `Blocked`) and only the last is drawn dim. So the vetting route now carries "First: you have no persona yet, so this starts by creating one", stated as what happens next rather than as a refusal dressed up, and Enter on it opens the create-persona overlay. When the overlay closes having produced a persona, the join takes the route it interrupted — `resume_route` is what "carries on" reads from — rather than returning to the list for the same keypress a second time. An overlay dismissed with Esc leaves the route as it was, which is the row still saying what it starts with. `take_route` is split out of the keypress so both the key and the resume go through one path; the loop cannot send itself actions, so the resume calls it directly rather than re-dispatching. `N` stays bound and stays in the footer, but is no longer offered as the way past a blockage — it is now for someone who wants a second persona before choosing. Two assertions inverted with the behaviour, including `!available()` on the vetting route, which was the bug stated as a test. Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
This was referenced Sep 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
From running the join against Linux Kernel: Apply for vetting was greyed out with "applying needs a persona — Press n to create one", so on a community that vets, the one route the community is actually telling you about looked like the one you could not use — and the way forward looked like configuration work to go and do elsewhere.
The distinction the code was missing
Who has to supply the missing thing.
RouteOption.blocked: Option<String>becomesRouteState:Only
Blockedis drawn dim.available()is true forFirstStep— that is thewhole point of it.
What you see now
The vetting route is live, and carries a line under it:
Stated in the second person and in order — what happens next, not a refusal
dressed up. Enter opens the create-persona overlay (#348), and when it closes
having produced a persona the join takes the route it interrupted, rather
than returning you to the list to press the same key again.
resume_routeiswhat that reads from.
An overlay dismissed with Esc leaves the route as it was — the row still saying
what it starts with — because the resume only fires when the step actually
produced what the route was waiting for.
Structure
take_routeis split out of the keypress so the key and the resume go throughone path. The join loop cannot send itself actions (
StateHandlerhas noaction_tx— it receives), so the resume calls the method directly rather thanre-dispatching, and the overlay is opened through the shared pure nav reducer.
Nstays bound and stays in the footer, but is no longer presented as the waypast a blockage; it is now for someone who wants a second persona before
choosing.
Testing
cargo fmt --all,cargo clippy --all-targets --all-features— cleancargo test --all-features -- --include-ignored— all greenRUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features— cleanTwo assertions inverted with the behaviour, which is the honest summary of
the bug:
applying_needs_a_persona_but_an_open_request_does_notasserted!available()on the vetting route. That assertion was the bug, writtendown and passing.
applying_without_a_persona_points_at_the_key_herechecked the blockedsentence named
n; it now checks the route is takeable and announces itsfirst step.
New:
only_what_the_join_cannot_supply_is_blockedpins the line between the twostates, and
a_route_that_starts_with_a_step_says_what_it_starts_withpins thatthe note renders.
Not covered
The resume itself — overlay closes, join carries on into the application — has
no test, for the same reason #348's mint has none: it needs a VTA. That is the
part to watch on the live run, and the failure shape is landing back on the
routes list instead of in the application.