Public Access
Make Connections the place a connection is made, and put the keychain away
Four changes to the phone, and the last one needed the connect path taking apart. **The bottom bar is three entries.** The keychain moved onto the hub, which is now SETTINGS with a gear rather than MORE with a hamburger. A bottom bar is for the places a session moves between, and keys, credentials and tags are managed occasionally and then left alone — which is the shape of everything already behind that hub. With the keychain on it, "more" stopped being a description of what is there. `ShellScreen.Vault` joining `IsMoreSurface` is the whole of the change: the tab that lights, the header that stands down and the back gesture's first case all read that one property, which is why the switch mirrors it by construction rather than by a second list. The keychain screen grew the header every hub screen has, because the shell's own is not above it any more and without one there would be no back arrow and nothing saying what the list is. The desktop keeps its Keychain rail entry. A rail with nine slots has room, so this is the second thing the two heads arrange deliberately differently, after the hub itself. **Terminal became Connections**, and the word does more work than a rename usually does — see below. The enum member stays `ShellSurface.Terminal`, for the reason the tab was never called Vault: the surface is a terminal, and the word a user reads is the product's. **The + puts the software keyboard away.** It sits above a terminal somebody is typing into, so the sheet it raises was arriving underneath a keyboard covering the half of the screen the sheet is on — and worse, laid out into the strip left above it, since the keyboard's inset shortens everything this head draws. Avalonia cannot do this and it is worth knowing why: `TopLevel.InputPane` reports the keyboard and offers nothing that closes one, because the framework's model is that it belongs to whatever has focus — and this keyboard was raised by the `WebView`'s own text input, by a native view Avalonia's focus manager never owned. Clearing Avalonia's focus leaves it exactly where it is. So `Platform/SoftKeyboard.cs` asks `InputMethodManager`, off the decor view's window token, and every step of it is allowed to be absent. **With nothing open, Connections is a connect screen rather than an empty state.** A box taking `user@host` or `user@host:port`, a password, and the machines most recently connected to underneath. The box is the only path in this product to a machine the keychain has never heard of, which is a real case it had no answer for: an address somebody was handed five minutes ago. A typed password and nothing else — offering the keychain's keys would be a second binding resolution beside `TryBuildAuthentication`, and the argument against a second one is written there at length. Nothing typed is saved, and the screen says so: a machine worth keeping belongs on HOSTS, where it can carry a key, a group's defaults and a name. The recents come out of the vault's own connection log rather than a list kept in this process, so they survive a restart and arrive on a new phone with the keychain. Deduplicated by address, because this is a list of places and not of events, and capped at six so the box stays above the keyboard. Emptied when the vault is — they are decrypted entries naming where somebody works, and a lock that left them on screen would be a list still readable after every key that decrypted it was zeroed. Tapping one leads to whichever of two things it is: a keychain host goes to that host's connect bar, where its key, its password box and its refusals already live, and an address goes back into the box, without the password, whose absence is the point of that path rather than a gap in it. **The connect path was shaped like `HostRowViewModel` all the way down.** The log entry, the identification, the failure record and the retry all took a row. They take a four-field `ConnectionTarget` now, so a connection to an address shares the ladder of refusals, the host-key question and the tab's lifecycle rather than growing a second copy of them. `ConnectionRecorder.Record` and `Identify` have always taken a nullable host id, so the log could already hold a connection with no item behind it. One behavioural change falls out of that and it is the one to know about: **trusting a host key now retries the attempt that raised the question** instead of re-running whichever host is selected. That was correct while a selected host was the only way to connect; with a manual target it would dial a different machine, or refuse with "choose a host first" over a key the user has just agreed to trust. The test selects a host first, so a regression cannot pass by connecting to the wrong thing successfully. `LogsViewModel.ReloadAsync` split so the connections half can be read alone. Reading the keychain's activity for a screen that offers neither would double the decryption on the list that was already the expensive one. Twelve tests: the parse grammar as a theory over seven refusals, the dialled request, the retry, and both branches of tapping a recent row. The recents rows are built by hand rather than connected-and-closed — what those tests are about is which branch a row takes, and driving it through the recorder's queue would test the recorder, which `DodoSSH.Client.Session.Tests` already does. What needs a device is phases 11.6 to 11.9 of `docs/manual-checks.md`.
This commit is contained in:
@@ -268,11 +268,20 @@ the reasoning behind it. Sign in, unlock, browse hosts, open a shell, and read t
|
||||
host-key decisions and the counted delete confirmations are there too, and none of them were softened to
|
||||
fit 360dp.
|
||||
|
||||
Its interface is the **v2 design**: four destinations in a bottom bar — Hosts, Terminal, Keychain and More
|
||||
— with snippets, SFTP, S3 buckets, logs and preferences one tap deeper behind the last. Both heads are on
|
||||
that design now; the desktop's own v2 is a 190-pixel labelled sidebar in place of the icon rail, a centred
|
||||
search box in the titlebar, and session tabs as pills. Its light theme is not built — see
|
||||
[`docs/design-import-gaps.md`](docs/design-import-gaps.md) — so the application is dark on both.
|
||||
Its interface is the **v2 design**: destinations in a bottom bar, with the rest one tap deeper behind the
|
||||
last. The bar is three — **Hosts**, **Connections** and **Settings** — with the keychain, snippets, SFTP,
|
||||
S3 buckets, logs and preferences behind Settings. A bottom bar is for the places a session moves between,
|
||||
and managing keys is not one of those. Both heads are on that design now; the desktop's own v2 is a
|
||||
190-pixel labelled sidebar in place of the icon rail, a centred search box in the titlebar, and session tabs
|
||||
as pills, and it keeps its Keychain entry — a rail with nine slots has room. Its light theme is not built —
|
||||
see [`docs/design-import-gaps.md`](docs/design-import-gaps.md) — so the application is dark on both.
|
||||
|
||||
**Connections is where a connection is made, not only where one is shown.** With nothing open it offers a
|
||||
box taking `user@host` or `user@host:port` and a password, and lists the machines most recently connected
|
||||
to underneath. That box is the one path in the product to a machine the keychain has never heard of — the
|
||||
case somebody has just been handed an address — and nothing typed into it is saved: a machine worth keeping
|
||||
belongs on Hosts, where it can carry a key, a group's defaults and a name. Tapping a recent machine goes to
|
||||
its host if it has one and back into the box if it does not.
|
||||
|
||||
**A connected phone shows one bar and then the terminal.** The header, the session strip and the bottom
|
||||
bar are collapsed while a shell is up, and a single 35-pixel row replaces them: back on the left, the
|
||||
|
||||
Reference in New Issue
Block a user