The tray (Composer.tsx:744-767, app.css:1734-1775) shows 72px squares with no filename for images, no size, no spoiler option; the remove button uses a hard-coded rgba and a red X.
Dropping files (FileDrop.tsx:127-133) opens a modal and sends each file immediately as its own message - no caption, and no Discord batching (the composer now sends up to ten as one message).
Fix: tray cards with filename, size, a spoiler toggle on Discord (daemon: prefix SPOILER_ in send_attachments) and a token-coloured remove; dropped files go into the composer's tray.
Part of the v1.0 UI pass.
- The tray (Composer.tsx:744-767, app.css:1734-1775) shows 72px squares with no filename for images, no size, no spoiler option; the remove button uses a hard-coded rgba and a red X.
- Dropping files (`FileDrop.tsx:127-133`) opens a modal and sends each file immediately as its own message - no caption, and no Discord batching (the composer now sends up to ten as one message).
**Fix:** tray cards with filename, size, a spoiler toggle on Discord (**daemon:** prefix `SPOILER_` in `send_attachments`) and a token-coloured remove; dropped files go into the composer's tray.
_Part of the v1.0 UI pass._
Salastil
added this to the v1.0 milestone 2026-10-07 20:43:17 -04:00
The tray is now a row of cards, and a dropped file goes into it instead of being sent on the spot.
Cards: a preview, the file name and its size (read by main - new fileSize IPC), and a remove button on the token danger colour instead of the hard-coded rgba/red X. The buttons fade in on hover or keyboard focus.
Spoiler toggle (Discord): an eye button on each card blurs its preview with a SPOILER pill; the daemon sends it as SPOILER_<name>, which is how Discord hides an attachment (nobilis 0f5669b, tested). Survives a retry of a failed send.
Dropping files (FileDrop): no more "Upload to #x?" dialog that sent each file as its own message. The files land in the composer's tray beside anything already there, can be captioned and reordered/removed, and go with the next message - up to ten as one message on Discord. Previews of dropped pictures come from the dropped file itself, since the media protocol only serves what the daemon cached or the user picked in a dialog. Services that can't carry files say so in a toast.
The size formatter is shared now (humanSize in lib/util), replacing three near-copies.
The first pair is the tray itself - the "before" is the old tray drawn from its markup, because nothing in the old build could put files in the tray without a dialog or the clipboard. The second is a real file dropped on the window, before and after.
Tray - before (top), after (bottom, the last card marked as a spoiler, the pointer over the first):
Dropping a file - before (top), after (bottom):
Finished: [15e7061](https://git.salastil.com/Salastil/moho/commit/15e7061f972889bdf2ece96a86621ef6440e7a57).
The tray is now a row of cards, and a dropped file goes into it instead of being sent on the spot.
- **Cards:** a preview, the file name and its size (read by main - new `fileSize` IPC), and a remove button on the token danger colour instead of the hard-coded rgba/red X. The buttons fade in on hover or keyboard focus.
- **Spoiler toggle (Discord):** an eye button on each card blurs its preview with a SPOILER pill; the daemon sends it as `SPOILER_<name>`, which is how Discord hides an attachment (nobilis 0f5669b, tested). Survives a retry of a failed send.
- **Dropping files** (`FileDrop`): no more "Upload to #x?" dialog that sent each file as its own message. The files land in the composer's tray beside anything already there, can be captioned and reordered/removed, and go with the next message - up to ten as one message on Discord. Previews of dropped pictures come from the dropped file itself, since the media protocol only serves what the daemon cached or the user picked in a dialog. Services that can't carry files say so in a toast.
- The size formatter is shared now (`humanSize` in `lib/util`), replacing three near-copies.
The first pair is the tray itself - the "before" is the old tray drawn from its markup, because nothing in the old build could put files in the tray without a dialog or the clipboard. The second is a real file dropped on the window, before and after.
Tray - before (top), after (bottom, the last card marked as a spoiler, the pointer over the first):

Dropping a file - before (top), after (bottom):

Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
FileDrop.tsx:127-133) opens a modal and sends each file immediately as its own message - no caption, and no Discord batching (the composer now sends up to ten as one message).Fix: tray cards with filename, size, a spoiler toggle on Discord (daemon: prefix
SPOILER_insend_attachments) and a token-coloured remove; dropped files go into the composer's tray.Part of the v1.0 UI pass.
Finished: 15e7061.
The tray is now a row of cards, and a dropped file goes into it instead of being sent on the spot.
fileSizeIPC), and a remove button on the token danger colour instead of the hard-coded rgba/red X. The buttons fade in on hover or keyboard focus.SPOILER_<name>, which is how Discord hides an attachment (nobilis 0f5669b, tested). Survives a retry of a failed send.FileDrop): no more "Upload to #x?" dialog that sent each file as its own message. The files land in the composer's tray beside anything already there, can be captioned and reordered/removed, and go with the next message - up to ten as one message on Discord. Previews of dropped pictures come from the dropped file itself, since the media protocol only serves what the daemon cached or the user picked in a dialog. Services that can't carry files say so in a toast.humanSizeinlib/util), replacing three near-copies.The first pair is the tray itself - the "before" is the old tray drawn from its markup, because nothing in the old build could put files in the tray without a dialog or the clipboard. The second is a real file dropped on the window, before and after.
Tray - before (top), after (bottom, the last card marked as a spoiler, the pointer over the first):
Dropping a file - before (top), after (bottom):