Skip to content

feat(upload): non-blocking dialog, concurrency queue, honest states#49

Merged
Nic-dorman merged 4 commits intomainfrom
feat/nonblocking-upload-dialog
Apr 23, 2026
Merged

feat(upload): non-blocking dialog, concurrency queue, honest states#49
Nic-dorman merged 4 commits intomainfrom
feat/nonblocking-upload-dialog

Conversation

@Nic-dorman
Copy link
Copy Markdown
Contributor

Summary

  • Dialog is dismissible at every pre-payment stallqueued_for_quote, quoting, awaiting_approval, queued_for_upload — without cancelling the underlying job. Pinia FileEntry holds the quote state; the dialog is a thin view bound to fileIds. Clicking a pending row in the uploads table reopens the dialog for that entry.
  • New upload_concurrency setting under Settings -> Advanced (default 1, range 1-8). Queued rows show "Queued: quoting" or "Queued: uploading" instead of blasting the network in parallel. Approve is gated on every entry being ready; button pluralises to "Approve N Uploads".
  • No more fake cost values: dropped the bytes / MiB * 0.05 ANT heuristic and the size-derived payment-mode fallback. Both dialogs now show an explicit "Not connected to the Autonomi network -- cost estimate unavailable" with a Retry button, checked before any spinner so the user is never left watching one that will never resolve.
  • Connection-aware row status: "Connecting to network...", "Obtaining quote...", or "Network unavailable" instead of the ambiguous "Preparing upload...". New StatusBadge entries so they don't fall back to ?.
  • Buttons grouped by intent: [Close] [Cancel Upload] on the left, [Approve Upload] isolated on the right -- a fat-finger on dismiss can no longer accidentally spend ANT.
  • Pinia HMR: files and settings stores now acceptHMRUpdate so getter/state changes don't require a full dev-server restart.

Test plan

  • Pick a file while disconnected -> row reads "Connecting to network..."; once online, flips through "Obtaining quote..." to "Ready to approve".
  • Pick 3 files with concurrency=1 -> first is "Obtaining quote...", others "Queued: quoting"; promotes one at a time as each completes.
  • While some entries are still quoting, Approve is disabled and the readout reads "Ready: X of 3".
  • When all entries reach awaiting_approval, Approve enables and reads "Approve 3 Uploads".
  • Close the dialog mid-quote -> dialog dismisses, rows stay pinned, clicking a row reopens the dialog for that entry.
  • Cancel Upload on a queued / quoting / awaiting_approval row -> row disappears.
  • Disconnect mid-quote -> dialog shows "Not connected" error with Retry; row label switches to "Network unavailable".
  • Settings -> Advanced: bump concurrency to 2 -> next pick of 3 runs two in parallel, one queued. Persist across restart.
  • Existing upload history loads as before (no datamap regressions); StatusBadge still shows ? for any unexpected label.
  • Cross-platform: at minimum Windows + macOS.

🤖 Generated with Claude Code

Nic-dorman and others added 4 commits April 22, 2026 15:21
- Dialog is a thin view bound to FileEntry ids; Pinia store holds quote
  state so the dialog can be closed/reopened at any pre-payment stall
  without cancelling the underlying job. Row click on a pending entry
  reopens the dialog for that entry.
- New upload_concurrency setting (Settings -> Advanced, default 1, range
  1-8). Queued rows show "Queued: quoting" or "Queued: uploading" until
  a slot opens. Approve is gated on every entry being awaiting_approval
  and the button pluralises to "Approve N Uploads".
- Removed the bytes/MiB * 0.05 ANT cost heuristic and the size-derived
  payment-mode fallback. Both dialogs now show an explicit "Not
  connected" error with a Retry button instead of any fake value.
- Row status is connection-aware: "Connecting to network...", "Obtaining
  quote...", or "Network unavailable" instead of the ambiguous
  "Preparing upload...".
- Button row grouped by intent: [Close] [Cancel Upload] on the left,
  [Approve Upload] isolated on the right so a fat-finger on dismiss can
  no longer spend ANT.
- Pinia stores acceptHMRUpdate so getter changes don't require a full
  dev-server restart.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…roof

The previous watch used a single getter returning a fresh array every tick,
which Vue compared by reference and so the callback always fired — but the
dependency tracking on array elements got tangled: after the first file's
quoting finished, the scheduler sometimes didn't see the quotingCount drop
and the second queued file never got promoted. watchEffect tracks every
reactive read automatically, which is the right tool for this job.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ant-core's estimate_upload_cost deliberately returns storage_cost_atto="0"
and estimated_gas_cost_wei="0" when every sampled chunk of a file is
already on the network (chunk_count <= 5, sampled == chunk_count). The
old UI rendered that as "0 ANT" and "+ 0.000000 ETH gas", which is
indistinguishable from a suspiciously cheap quote.

- New alreadyStored flag on FileEntry, set in beginQuoting when both
  cost fields are "0" and chunk_count > 0.
- Dialog cost box shows a green "Already stored on the network -- free"
  banner when every entry is stored, plus per-entry "Already stored"
  badges in the file list. Mixed batches get a note on the cost card.
- Uploads table cost cell reads "Free -- already stored" for those rows.
- The "estimated from a single network quote" disclaimer is hidden for
  the all-stored case (no estimate to vary).

The upload flow itself is unchanged -- start_upload returns
payment_required=false and confirm_upload runs as a no-op on already-
stored chunks, so Approve still does the right thing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Already-stored entries now skip awaiting_approval entirely — the store
routes them directly into queued_for_upload, the scheduler drives them
through to complete, and the confirm dialog auto-dismisses when every
selected entry is in that state.

- Row status collapses all the intermediate no-op states (queued_for_upload,
  the second-time quoting inside startRealUpload, paying, uploading) to
  a single honest "Saving datamap…" label. User sees a clean
  Obtaining quote… -> Saving datamap… -> Complete sequence instead of
  a confusing flash through Paying / Uploading for a free file.
- Dialog canApprove, readyCount, and button label now count only
  non-stored entries, so a mixed batch (some stored, some not) behaves
  correctly: stored entries process in the background while the user
  approves the rest.
- Dialog auto-closes with a toast ("N files already stored — saving
  datamap") when every selected entry is alreadyStored. No ceremonial
  click required for a free, no-decision-needed operation.
- StatusBadge has an entry for the new "Saving datamap…" label so it
  doesn't fall back to ?.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Nic-dorman Nic-dorman merged commit 50bcce3 into main Apr 23, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant