refactor(ui): one empty state, and loading is not one of them - #85
Merged
Conversation
C3 was planned as one item and is two. The dedup is mechanical; giving empty states the next action `UI_SPEC.md` asks them for is a change of copy and behaviour with new catalogue strings. This is the first half, and it changes no pixels. Three helpers rendered the same centred muted line three ways — `empty` in the diff, `placeholder` in the detail pane, and a third `placeholder` in staging that reached the same result through `center_x` and `center_y` instead of `center`. They are one function now. Reading the seven call sites turned up something the dedup would otherwise have cemented: two of them are not empty states at all. "Loading…" and "Reading the conflicted file…" are a pane that has not finished looking, which is a different thing from a pane with nothing in it — and the difference is about to matter, because an empty state is getting a next action and a loading state has none to offer. So there are two functions with one body, for the same reason `cherry_pick` and `revert` are separate despite their near-identical shape: the distinction is in what the caller means, and folding it away is how it gets lost. Three diff call sites passed `&format!(…)` and relied on the old helper calling `to_owned` for them. They pass the `String` now, so the allocation is visible at the call site rather than hidden behind a `&str` parameter that could not actually borrow. The audit is recorded in `UI_SPEC.md` rather than left implicit: most empty states still only describe the absence, and only the welcome screen and the PR panel carry an action. Naming the gap is what makes the second half a defined piece of work instead of a vague intention.
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.
C3 was planned as one item and is two. The dedup is mechanical; giving empty states the next action
UI_SPEC.mdasks for is a change of copy and behaviour with new catalogue strings. This is the first half, and it changes no pixels.The dedup
Three helpers rendered the same centred muted line three ways:
diff.rsempty.center(Fill)detail.rsplaceholder.center(Fill)staging.rsplaceholder.center_x(Fill).center_y(Fill)What reading the call sites turned up
Two of the seven are not empty states at all. "Loading…" and "Reading the conflicted file…" are a pane that has not finished looking — a different thing from a pane with nothing in it.
The difference is about to matter: an empty state is getting a next action, and a loading state has none to offer. Folding them together now would have cemented the confusion exactly when it starts to cost something.
So there are two functions with one body, for the same reason
cherry_pickandrevertare separate despite their near-identical shape: the distinction lives in what the caller means, and collapsing it is how it gets lost.A smaller thing
Three diff call sites passed
&format!(…)and relied on the old helper callingto_ownedfor them. They pass theStringnow, so the allocation is visible at the call site rather than hidden behind a&strparameter that could not actually borrow.The audit, recorded rather than implied
UI_SPEC.mdnow says which empty states carry an action — the welcome screen and the PR panel — and that the rest only describe the absence. Naming the gap is what makes the second half a defined piece of work rather than a vague intention.While counting them I also noticed "Select a file to see its changes" is written out in two files. That is copy duplication rather than code duplication, and it belongs with the ~690 inline literals the i18n migration still has to move, so it is left alone here.
Testing
The migration is covered by the render tests that already exist — they assert these exact strings reach the screen, so a broken call site fails them. No new assertion is honest here:
emptyandloadingrender identically today, and a test claiming to tell them apart would be testing a name.Sabotage: re-adding
fn placeholdertodetail.rsfailsno_view_file_draws_its_own_rule_or_buttonwith "widget/detail.rs defines its ownfn placeholder". The guard grewfn placeholderalongside the rules and button roles it already refused.Gate
cargo fmt --all -- --check,cargo clippy --workspace --all-targets --all-features --locked -- -D warnings,cargo test --workspace --all-features --locked— 900 tests, all green.