The expected experience for the whole task: a member drops an image or document into a channel, watches it upload, and everyone sees it as an inline preview or a file card — stored privately, scoped to the workspace. These are static mockups of the prepped spec, not the live app.
Capture → store → renderImages · PDF · text10 MB / filePrivate bucket · RLSAgent reads it → next rung
01
Attach
Paperclip, drag-drop onto the chat, or paste an image from the clipboard.
02
Preview
Files appear as removable chips above the box. Bad types are rejected here.
03
Send
Uploads to private storage, then posts the message with the attachment.
04
Deliver
Image preview or file card in the feed — live for every channel member.
The flow, state by state
What the member sees
Step 01 Three ways to attach
The composer gains a paperclip
Tap the paperclip to pick a file, drag one onto the chat, or paste an image straight from the clipboard.
#general4 members
N
Nok
Can you drop the warehouse layout here?
Message #general
Step 01 Drag-and-drop
Drop anywhere on the chat
Dragging a file over the channel reveals a drop target so it's obvious the message area accepts files.
#general4 members
N
Nok
Can you drop the warehouse layout here?
Drop to attach
images · PDF · text · up to 10 MB
Message #general
Step 02 Before sending
Removable preview chips
Attached files stage above the box with a thumbnail, name, and size. Remove any before sending; add a caption if you like.
#general4 members
N
Can you drop the warehouse layout here?
warehouse-layout.png
2.1 MB
✕
PDF
acme-proposal.pdf
840 KB
✕
Here's the current layout + the proposal
Step 02 When it can't be attached
A clear reason, never a silent drop
Wrong type or over the 10 MB cap is caught in the composer with a plain message that says what to do.
#general4 members
N
Can you drop the warehouse layout here?
Can't attach site-plan.tiff — TIFF isn't supported. Use JPG, PNG, GIF, WebP, PDF, or text.
drone-shot.png is 14 MB — files must be under 10 MB.
Message #general
Step 03 On send
Your bubble appears while it uploads
An optimistic bubble shows the local preview with a spinner and a sending… state. The text send stays offline-durable; the file needs a connection.
#general4 members
N
Can you drop the warehouse layout here?
warehouse-layout.png
Here's the current layout + the proposal
uploading… 68%
Message #general
Step 04 Delivered
Image preview + file card in the feed
Images render inline; documents render as a tappable card that opens the file. The raw file is preserved in private storage.
#general4 members
warehouse-layout.png
Here's the current layout + the proposal
PDF
acme-proposal.pdf
840 KB
✓ Sent · 2:14 PM
Message #general
Step 04 Every member, live
Teammates receive it over Realtime
The same preview and card arrive on Nok's screen instantly — RLS lets in only workspace members, so the file stays inside the workspace.
#generalNok's view
K
Krit
warehouse-layout.png
Here's the current layout + the proposal
PDF
acme-proposal.pdf
840 KB
2:14 PM
Perfect, opening it now 👀
Message #general
Step 01 Clipboard paste
Paste a screenshot straight in
Copy an image anywhere and paste into the box — it stages as a chip just like a picked or dragged file.
#design3 members
M
Can you show me the error screen?
Pasted image
just now · 620 KB
✕
Here it is 👇
What holds it together (behind the glass)
Private, workspace-scoped storage. Files land at attachments/{workspace}/{channel}/… in a private bucket; Row-Level Security lets a member touch only their own workspace's folder. Previews load through short-lived signed URLs.
Durable once sent. The message row + stored file survive reload and reconnect — reopen the channel a day later and the layout and proposal are still there, traceable to the original file.
Caught early. Type and the 10 MB cap are checked in the composer and enforced by the bucket, so a bad file never becomes a broken message.
Where it stops. This rung is capture, store, and show. The channel agent reading the attachment and replying is the next rung — Capture v2, filing its content into the shared knowledge graph.