Repository navigation
compose: a message can carry several files, not just the first one dropped - #82
Conversation
…opped Dropping five photos attached one and discarded four in silence — the drop handler took urls[0] and draftPath was a single string. A drop that loses most of what you dropped, with no message, is worse than one that refuses. Drafts are a list now. Drag-and-drop queues every file it was given, /attach and Ctrl+V append rather than replace, and each chip removes only itself. Sends go out one part per file in queue order through the existing send-file.ts path (unchanged: still one file per invocation, still stdin, still refusing groups whose guid is unknown). The caption rides the first part alone, or five files would post the same sentence five times. Two things a batch has to survive. The service is captured when it STARTS, never re-read from root.active per part, so switching threads mid-send cannot push a later part onto a different service (war room #2). And a failing part stops the batch, leaves the remaining files attached and says how many are left, instead of making the user work out which of five actually went. Capped at ten files: a stray drop of a whole folder should be refused, not turned into eighty sends. Chips are one per row for the reason the received ones are — a RowLayout of N sums implicit widths and drags the conversation column past the panel edge, taking every right-aligned element with it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xxS9WCT7ifHhbDjYyGnHS Co-authored-by: zachwilke <zachwilke@users.noreply.github.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1df07c8ea1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| function removeAttachment(path) { | ||
| root.attachDrafts = root.attachDrafts.filter(function(d) { return d.path !== String(path) }) |
There was a problem hiding this comment.
Remove deleted files from the active send queue
While the first part is in flight, clicking ✕ on a later attachment only removes it from attachDrafts; the fileQueue snapshot still contains that path, so pumpFileSend() subsequently transmits a file the user explicitly removed. Either remove not-yet-started paths from fileQueue as well or disable removal for the active batch.
AGENTS.md reference: AGENTS.md:L8-L10
Useful? React with 👍 / 👎.
| if (root.fileQueue.length === 0) return | ||
| var path = root.fileQueue[0] | ||
| root.fileQueue = root.fileQueue.slice(1) | ||
| root.sendDraftPath = path |
There was a problem hiding this comment.
Move the file-send state machine into tested TypeScript
This adds batching decisions—queue advancement, ordering, caption consumption, and retry state—directly to QML, while the new tests only search the QML source for strings and cannot execute these transitions. Extract this state machine into TypeScript and unit-test success, failure, removal, and navigation transitions, leaving QML to render and dispatch effects as required by the repository.
AGENTS.md reference: AGENTS.md:L17-L19
Useful? React with 👍 / 👎.
| addAttachment(p) | ||
| composeField.text = "" | ||
| note = "attached — type a caption or press Enter to send" | ||
| note = root.attachCount > 1 | ||
| ? root.attachCount + " files attached — caption, or Enter to send" | ||
| : "attached — type a caption or press Enter to send" |
There was a problem hiding this comment.
Preserve the attachment-limit error for
/attach
When ten files are already queued, addAttachment(p) reports the limit and returns without adding the requested path, but these following assignments clear the command and overwrite that error with “10 files attached.” The user is therefore told the command succeeded and may send a batch that silently omits the requested file; only clear the field and show the success note when an attachment was actually added.
Useful? React with 👍 / 👎.
|
Merged, thanks @zachwilke! every dropped file goes out, with the caption on the first one. Fixing the chat and service when the batch starts closes the switch-threads-mid-send hole. It's in main as of 186b536 and deployed on my machine. I merged it together with nine other PRs, and all 526 tests pass on the combined tree. |
WHAT: CHANGE.log is a running, newest-first log of every change since the last X post, each entry naming the person with real name, GitHub login and their X account as a https://x.com/<handle> link. X-POSTS.md is the queue of posts for @nixfred: Post 1 (CONTRIBUTORS-X-POST.md, 2026-09-11) marked posted, Post 2 drafted covering the 19 merged PRs since (#54 #71-#77 #80-#82 #84 #85 #87 #88 #92-#95) plus 4bad82d and 481e555. WHY: Fred's standing rule 2026-09-16. Handles were missed before; a thank-you without the @ never reaches the person, and a wrong @ tags a stranger. HANDLES: verified @jondkinney (GitHub profile), @zachwilke_1 (pinefall.dev), @bbishdotdev (bbish.dev + name), @mwhuss (name + Omarchy posts replying to @nixfred). @jefehoser likely (same login, Omarchy posts), flagged for Fred. Ian Swope and cjoh: none verified, recorded as checked. .gitignore: *.log swallowed CHANGE.log, so it is re-included explicitly. LR-T: blip, changelog, x-posts, contributors, handles LR-D: blip, docs, community LR-K: change-log-verified-x-handles, x-post-queue Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ainpzHJ5F7nsV4hB6HpZy
Split out of #47 (third of five, as requested). Rebased onto current
main(2.5.0). Independent of the UTC and GIF PRs.What
A dropped, pasted, or
/attached set of files all stay on the draft. They ship one part per file, caption on the first only, capped at ten. A failing part stops the batch and leaves the rest attached.Why
Dropping five photos attached one and discarded four in silence: the handler read
urls[0]and the draft was a single path. A drop that loses most of what you dropped, with no message, is worse than one that refuses.Sends go through the existing
send-file.tspath (unchanged: still one file per invocation, still stdin, still refusing groups whose guid is unknown). The service is captured when the batch starts, never re-read fromroot.activeper part, so switching threads mid-send cannot push a later part onto a different service (war room #2).Chips are one per row, for the implicit-width reason the received ones are.
mainalready usesdraftsfor the per-conversation text draft map, so the attachment list isattachDrafts/attachCount/addAttachment(s)/removeAttachment/clearAttachments.How it was verified
bun testis green (new QML invariants for drop-all-files, the cap, caption-on-first, one-chip-per-row, service capture)CLAUDE.md→ named below, and the doc updated if it changedinvariants touched: Never send to a handle for a group (still
--chat-id/--tovia send-file.ts); Message text never rides argv (caption still--caption-stdin); Never let one delegate's implicit width exceed the panel (chips one per row).Rebase notes
pumpFileSendsits next to current-main's richercopyProc(clipboard feedback). The QML tests that used to slice toProcess { id: copyProc }now slice tofunction copyText, becausecopyProcis no longer a one-liner.Supersedes the multi-file slice of #47 (
20f8bc1).