monorepo finale: relocate crates, monitor release pipeline, docs overhaul - #1234
Draft
lollipopkit wants to merge 265 commits into
Draft
monorepo finale: relocate crates, monitor release pipeline, docs overhaul#1234lollipopkit wants to merge 265 commits into
lollipopkit wants to merge 265 commits into
Conversation
- opt.: interval must <= 10s - fix: speed wrong push unit - fix: wrong segments count - fix: threshold: parse endIdx
- new: add time for msg - new: `rate` for push - opt.: interval
- fix: push - opt.: push logic
The way out was the way in played backwards, so it reuses the same machinery: capture where the thing is now, let the layout change, then measure where it landed and move a copy between the two. One key marks both ends. The compact row and the grid card can never be on screen together — the row exists only while the pane is open, the card only while it is closed — so a single anchor is unambiguous, and one `GlobalKey` with one holder is worth more here than two that each need watching. The row carries the anchor while merely selected, not only while flying: closing has to measure it *before* the rebuild that takes the pane away, and by then there is nothing left to ask.
Each direction now says what it is leaving as well as what it becomes: a card with its charts on one side, a card with only its title on the other. The row form is also what a card of a server that has never connected looks like, which is why the two read as one thing changing shape rather than two widgets swapped for each other.
`restorationId: 'tab_$id'` is interpolated where it is written, and where it is written is inside the callback `add` runs to build the session — before `add` has returned the tab whose id that is. Every attempt to open a terminal threw `LateInitializationError`. The tab's name works and is in scope there: unique among the open tabs, and restored in the same order, which is all a restoration key needs. The id stays for the close callback, which is only ever called later.
The per-tab navigator stack survives switching tabs, which had been marked as reasoning rather than something anything had run.
`enabled` read the setting once per build and nothing brought this page back to ask again — the setting lives on another page, and no provider carries it. So it applied whenever something unrelated happened to rebuild, which from the outside is indistinguishable from not working. Listened to now, the way the text-scale setting on this same page already is.
Two failures found on the way: the single-column setting was read once instead of listened to, and a second window caption was drawn on every page pushed inside a tab.
The tab strip sat above the local file page's own app bar, so the Files tab opened with two rows of chrome and half the height gone before any file. The local page now hands its buttons to the host through `actionsSink`, the same way the SFTP page already did, and draws no bar of its own when it has somewhere to hand them. Its title went with the bar, so it reports the folder it is showing as well, and the strip's leading tab carries that name beside its icon. Pushed on its own — the file picker — the page is unchanged and still self-contained.
This device was pinned to the head of the strip and servers were the only thing that could be a tab, so the two were not the same kind of thing even though browsing either is the same act. Nothing could hold two folders on this device at once either. The leading tab is now a picker listing this device and every server, and both open as ordinary tabs. `_FileSession` is sealed over the two: they differ in what it takes to reach them and in nothing else a tab cares about. Restored state tells them apart by the absence of `serverId`, which every record written before this carries, so tabs saved by an older build come back as the server tabs they were.
Both pages now read like the server list: the picker on the left, what it opens on the right, one draggable divider between them, and the same `forceSinglePane` setting and stored width. The picker is the first tab only while there is no column for it. Its width threshold also requires something to be open, so a fresh launch spends the whole window on the picker rather than reserving a column beside nothing. The SSH add-server button moved onto the picker itself, which is where it acts. It used to hang off the tab page and check the selected index to decide whether to show itself; now it is simply part of the page it belongs to, and follows that page into the column.
On a wide screen both pages now show the rail on the left and, on the right, a plain bar naming the session that is on screen with that session's own buttons beside it. The strip stays on one screen, where there is no rail. The rail is not the picker in a narrower column. A grid of cards is for browsing and choosing; a rail is for switching while something else has your attention, and it carries the running sessions the picker has no business knowing about. Tapping a server in it always starts a new session — the section above is where switching happens, and a second shell on one server is an ordinary thing to want. For files, this device sits above the first heading rather than under one of its own: it is the place that is always reachable, not one entry among many. SSH gets an add-server button in the rail's toolbar, since a rail has no room for the picker's floating one.
It was a column of cards, each carrying the title row a card shows before it connects. Beside a detail pane that is a smaller copy of what the pane already draws, and it read as a third way of listing the same servers the terminal and file rails list. Now it is `SideBarTile`: the name, the fill on the one being shown, and the live mark on the ones that are connected — the same mark the terminal rail puts on a running shell. The flight lands on that row instead of a card, drawn selected, since a card only ever flies into the rail as the thing that was just opened. The rails elsewhere drop their addresses too. The narrow pickers keep theirs: those are cards at full width, where the second line costs nothing.
The server grid had its own copy of the round-robin split — a `ListView` per column, each scrolling on its own. Server cards are the worst case for it: one that has not connected is a single line and one that has is several charts, so the columns ended up wildly uneven. They now flow into whichever column is shortest, in one scrollable, built as they come into view so the page watches the servers it is showing rather than all of them. `PageColumns` keeps its ceiling of three columns; the width it caps itself at is now derived from the grid's own arithmetic instead of a second copy of it. The pickers drop the spacing they had stacked up: one gap between two cards rather than a column gap, a scrollbar gutter and two card margins.
Terminal, SFTP, container and the rest acted on the server, not on any one card, but they sat at the top of the page as if they were its first card — so they scrolled away after the first chart and getting back to them meant scrolling to the top. They are now a bar over the page, reachable the whole way down, that slides out of the way while you read forward and comes back the moment you scroll back. The grid keeps room below its last card, so nothing ends up permanently under it. The row centres itself where it fits rather than being left-aligned in a container the width of the window, and scrolls where it does not.
A monitor-only server has one button, and the bar was still the full 640 it was capped at, with a lone Terminal floating in the middle of it. The row is now a `Wrap`, which reports the sum of its children as its intrinsic width, so an `IntrinsicWidth` above it can size the bar to what is actually in it — the cap only applies once there are enough buttons to reach it. The bar's height follows its contents too, and a language whose labels do not fit takes a second line rather than being clipped. The in-card row keeps the scrolling form: it is at the card's width either way, and there it is the width that is given rather than asked for.
They sat directly against each other and against the bar's edge, so seven buttons read as one block rather than as seven things to choose between. The outer inset is larger than the gap between them, which is what makes the row read as a group inside a border rather than as buttons that happen to be near an edge.
Three changes to the same row. It is a single line now, scrolling where it does not fit, instead of wrapping to a second one. Its ceiling is the page's width less 100, so there is always some of the page visible either side of it and it never reads as a second edge to the window. And 3 above and below the buttons rather than 14 — the buttons bring their own tap target, so the padding only has to keep them off the border. A shrink-wrapping viewport replaces the `Wrap`: it takes the width of what is in it and no more, and scrolls once whatever holds it runs out of room, so the bar still fits itself to one button without needing the intrinsic width the `Wrap` was there to report. The buttons' tap target comes down from the default 48 square, which in a bar this height was all of it.
A host reports as many mounts as it has, and most of them are loop devices and container layers. The throughput chart sat after that list, so on a real machine it was never seen; the mounts are now behind a disclosure that starts closed, with the chart above it — which is what the network card already does with its interfaces, for the same reason. Charts get room above them: at 7 the topmost axis label touched whatever heading was over it. The action bar keeps less space under its labels than over its icons. A line of text carries its own space beneath it, so equal padding reads as more.
An `IconButton` with a `Text` under it left the word inert, so half of what reads as one target did nothing. The label is now inside the button rather than captioning it, and the ink covers both. The bar is 3 shorter for it, and carries the height it needs for a 17pt icon over a line of 11pt text — at 52 the column overflowed it by a pixel.
It was a row in the SSH settings, which is where someone goes to change how terminals look, not to find a machine. Sweeping the network for hosts is what you do with an empty add-server form in front of you, so it is an action on that page's bar — and only while adding: on a server that already exists it answers a question nobody is asking. The behaviour is unchanged: it still adds every host picked, under one user typed once, rather than filling in the form. Discovery finds hosts, not accounts, and someone who went looking at their whole network usually wants more than one of what they found. The form is left alone for the server they were adding by hand.
The switch existed because neither place was good: on the card they crowded a grid of charts, and at the top of the detail page they scrolled away. They float over the detail page now, in reach on both layouts, so the question the setting asked no longer has two answers. Gone with it: the branch in `ServerFuncBtns` that drew a bare icon row for the card, the card's own row and the taller card height that made room for it, and `moveOutServerFuncBtnsHelp` in fifteen languages. The stored key stays until a release has passed, marked deprecated with a TODO. The settings entry is a single row again — the order of the buttons — instead of a disclosure holding one switch and one row.
Reached from the add-server page, a full-screen sweep that ended by adding servers left the form it was opened from sitting there untouched — the one thing on screen it should have had something to say to. It is a dialog over that form now, and picking a host writes into it: the address and the port, and the name as well while that field is still empty, where the address is what someone would have typed anyway. Nothing else — a sweep finds hosts, not accounts, so there is no user, key or anything else to guess at. The banner stays on screen as the only way to tell two addresses apart, and goes nowhere: it names an SSH build, not a machine. One host at a time, so the multi-select and its bulk import go, along with `isSelected` on the model, kept one release for old persisted reports. The files move out of `view/page` — none of this is a page any more.
It said "tap the search button to discover SSH servers on your network". On a page that meant the labelled one filling the bottom corner; in a dialog it meant an 18pt icon in the top one, which is not something a line of grey text can point at. The empty view is the button now — labelled, in the middle, where the sentence was. The icon in the bar appears only once there are results for it to replace, so there is never more than one way to start the same sweep. `tapToStartDiscovery` goes in fifteen languages: it was directions to a control, which is what a control that can be seen does not need.
Resolves six conflicts, all where an upstream change landed on code this branch had already rewritten: - iOS Live Activity cleanup (#1265) turned `stop()` async; the accessory widget URL channel this branch added keeps its case. - Combined key+password auth (#1270) drops the either/or between the two. Applied through `spi.ssh` rather than the flat fields it was written against, and extended to the SSH-via-monitor credential, which is the same question asked about a second account. - The global Agent workspace (#1268) attached its terminal entry point to the tab strip this branch replaced with a rail; the button moves to the rail's session actions. Its status JSON reported a CPU with no sampling window as 0% — that field is nullable here precisely because a fabricated 0 reads as a genuinely idle machine, so it now reports null.
`raw.split(separator).isEmpty` is never true — `String.split` returns at least one element — so output the script never wrote passed the check and reached the parser, which produced an empty status. The page then kept whatever its rolling state still held (cpu, network speeds) and blanked the rest, with nothing on screen saying why. That is exactly what a host answers once the script is gone from under it, and the default script directory is /tmp. Reported as a failure, the connection goes back through the connect path, which reinstalls it. The check is now for the marker itself, and accepts either — a custom command carries its own, and with every built-in status command disabled it is the only output there is. The message distinguishes nothing at all from something unparseable, and quotes it.
The code encodes the whole record — address, user, password, key id — as plain text. `QrShareBtn` put it straight on screen, so a code that hands over a server to anyone who photographs it looked like any other share button. It now opens a dialog that says so above the code. The width is capped rather than fixed: the QR fills whatever it is given and the warning is one long line, so on a desktop window their intrinsic widths would have made a QR code the height of the screen, while a narrow phone should still get less.
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.
Summary
This PR finishes the monorepo migration with three main blocks, plus follow-up hardening:
1. migrate: merge
rust/andrust_builder/intocrates/sbm_ffirust_root, pubspec paths, and per-platform glue updated in synccargo test --workspacegreen, 12/12 FFI parity tests pass,flutter build macos --debugbuilds through cargokit for real2. feat: monitor release pipeline
monitor-v*tags), decoupled from the app'sv1.0.xinstall.shrewritten for the new release layout; fresh installs generate a randomJWT_SECRET3. docs: full audit of the docs site (en/zh/ja/de/fr/es)
4. Follow-ups on this branch
Notes
server-box-monitorghcr image to public in package settings if desiredSummary
Changes