<feed xmlns='http://www.w3.org/2005/Atom'>
<title>meshbay.git/packages/meshbay-hub/src/meshbay_hub/static/transfers.js, branch 0.3</title>
<subtitle>MeshBay — read-only public mirror</subtitle>
<id>https://git.meshbay.org/meshbay.git/atom?h=0.3</id>
<link rel='self' href='https://git.meshbay.org/meshbay.git/atom?h=0.3'/>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/'/>
<updated>2026-08-15T13:48:36Z</updated>
<entry>
<title>fix(downloads): automatic really is automatic, and a selection downloads all of it</title>
<updated>2026-08-15T13:48:36Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-08-15T13:48:36Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=4066c754a613deb965472853fe69727d68be593e'/>
<id>urn:sha1:4066c754a613deb965472853fe69727d68be593e</id>
<content type='text'>
Two bugs in what shipped last, and both were mine.

Automatic mode still opened Save As, because with no folder granted the
code fell through to the file picker — while the documentation said it
would use the browser's own download folder. It does that now. Over
512 MB it still asks, since getting there means holding the file in
memory and a tab will not survive a 40 GB blob; Settings is where to stop
it asking again.

Selecting two files downloaded one. They were started without awaiting,
so each asked the browser for a save dialog at once, and a browser allows
exactly one — the rest were rejected and the errors went nowhere. They
are awaited one at a time now, which serializes the dialogs and not the
transfers: each call returns as soon as its transfer is registered.

Then the adjustments. The transfers widget offers Open on a finished
download that went into a granted folder — the bytes go to a new tab, and
that is the whole of what a page can do: no browser lets one start a
desktop application or show a file manager, so the folder half of that
request cannot be built and the guide says so.

The Files toolbar was four controls of three different heights in a row.
It is three groups now — what you can add, where you are, what you can do
with what is here — on one baseline, with icons from the set and a gap
between the dots and the word Actions. Chat comes first among the tabs
and is the one you land on. The three Discover entries in the sidebar
have icons. And a link in a chat message becomes a link: built as an
element and never as markup, http and https only, so `javascript:` is not
one message away from running here.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(files): transfers that outlive the page, and selection instead of per-row menus</title>
<updated>2026-08-15T11:13:08Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-08-15T11:13:08Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=41e2b79cb1bc9d188853aeff5a55cd2237268587'/>
<id>urn:sha1:41e2b79cb1bc9d188853aeff5a55cd2237268587</id>
<content type='text'>
Downloads and uploads were state inside GroupPage. Leaving a group
unmounted the component, its cleanup closed the DataChannel, and a
half-written file was all you had — which is also why only one thing
could be in flight at a time.

They live in a module-level store now. A group page hands its transport
over on the way out rather than closing it, and the last transfer using
it closes it; signing out is the one thing that cancels everything,
because those transfers are moving data on a token about to stop being
ours. The store is plain JavaScript with no browser globals, so
test_transfers.py runs it under Node and pins the parts that are timing
and lifetime rather than markup: that a cancel stops the work instead of
greying out a row, that a stalled transfer reads as stalled rather than
reporting its own historical average, and that a released transport is
closed by the last transfer and not before.

The widget by the bell shows each transfer with its rate and a cancel
button, so the Files panel no longer carries progress bars — you can
watch a 40 GB archive from the chat, or from another group.

Selection replaces the per-row menu: a Select toggle puts checkboxes on
files and folders, and ⋮ Actions acts on what is ticked. Ticks survive
walking into another folder, so a selection can span directories.
Downloads start together and run together. Videos offer Play only — View
did the same thing, which is the sort of duplication that makes people
wonder what the difference is.

Uploads had to become parallel-safe for any of this to mean anything:
their acks were matched by arrival order, so two at once credited each
other's progress. The node names the file in every ack, so they are keyed
by name now — with the same file twice refused, since the node keys its
own upload state that way too.

Two mistakes worth recording. The selection column went into the body
rows and not the header, because that edit matched nothing and I had not
made it assert; the columns were misaligned until a screenshot showed it.
And the Actions menu opened leftwards from a button at the right edge of
the toolbar, half of it off-screen.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
