diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-07 01:50:14 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-07 01:50:14 +0200 |
| commit | 375419c041a4523614b3a1b98fa54fb5acb1b8bf (patch) | |
| tree | 51086cd1e29a3f78f352dc2080847392a42fc37a /packages/meshbay-hub/tests/test_upload_controls_hidden.py | |
| parent | 435f54b382004de28196aa44c9b1d2c7368ae212 (diff) | |
| download | meshbay-375419c041a4523614b3a1b98fa54fb5acb1b8bf.tar.gz | |
fix(client): Save in the app panes was invisible, and Chat's never landed
Two defects behind one report — "you cannot always click Save, you do not
notice, and it does not work".
**It did not work, for Chat, systematically.** `_dispatch` resolves an admin ack
against the pending request and returns, which is right for an op whose caller
already knows the value it chose. Chat's pane calls `transport.setChatDirectory`
itself, so nothing told `group-page` anything: the node saved it, every *other*
connected client learned it from the broadcast, and the one that asked went on
showing an unsaved-looking draft. Clicking Save again just re-sent it. Same
shape as the root-ack bug, in a different message — so the set is now
`BROADCAST_ACK_TYPES`, named for the property that makes it true, and covers
`chat_directory`, `chat_link_preview` and `app_directories`.
**You could not notice, because Save was not visibly a button.** It carried
`btn btn-small btn-secondary`, and there is no `.btn` rule in the stylesheet at
all — so it took `.btn-secondary`: no background, a transparent border, dim grey
text. Enabled it already looked like a disabled control; disabled it was the
same thing at 40% opacity. Measured on a real page: enabled is now accent on
white, disabled is grey text on a plain border, and an inert one says why
("No changes to save") rather than leaving the reader to guess what the pane
counts as a change. Videos' second Save — the TMDB one — is the same control,
because two Save buttons in one pane that do not look alike is worse than
either looking wrong.
Verified by driving the real pane in Electron through the whole cycle: inert,
pick a folder, live, save, and the node's answer coming back to disable it
again. Four earlier readings said the enabled button was transparent; all four
were taken inside python's directory-listing page, which the app never runs in
— my scaffolding, not the code.
Hub suite only: the node package is untouched by this.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011pvMdvLBG92jyhvD5pD6us
Diffstat (limited to 'packages/meshbay-hub/tests/test_upload_controls_hidden.py')
| -rw-r--r-- | packages/meshbay-hub/tests/test_upload_controls_hidden.py | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/packages/meshbay-hub/tests/test_upload_controls_hidden.py b/packages/meshbay-hub/tests/test_upload_controls_hidden.py index bdba373..f6f476e 100644 --- a/packages/meshbay-hub/tests/test_upload_controls_hidden.py +++ b/packages/meshbay-hub/tests/test_upload_controls_hidden.py @@ -212,16 +212,17 @@ def test_the_notice_also_answers_the_operators_own_request(): caused it. Every other admin ack can be resolved and dropped, because its caller - already knows what it asked for and updates local state from that. The root - acks carry a whole table only the node can compute — availability, the name - it settled on, the eject a failed plug left in place — so resolving one - without handing it on left the operator who clicked Eject as the only - client that never saw it happen. + already knows what it asked for and updates local state from that. These + are the ones the node *broadcasts*: every other connected client learns the + change from it, and the one that asked is the only one that does not, + because its own request swallowed its copy. Found on the root table, then + again on Chat's directory — where it meant the pane went on showing an + unsaved-looking draft after a save that had worked. """ transport = TRANSPORT.read_text(encoding="utf-8") block = transport[transport.index("msg.type.endsWith('_ack')"):] block = block[:block.index("_uploaders")] - assert "ROOT_ACK_TYPES" in block and "_onRootsChanged" in block, ( + assert "BROADCAST_ACK_TYPES" in block and "_replayBroadcast" in block, ( "the initiating client resolves the ack and learns nothing from it") |