feat(Attachment): render live upload progress on messages being sent - #3295
MartinCupela wants to merge 9 commits into
Conversation
Ports #3277 onto v15. A message can now carry attachments whose uploads are still in flight: it appears in the list immediately, rendering the local preview with live progress, and resolves in place as the uploads settle. The progress UI reads `client.uploadManager` rather than the frozen `localMetadata.uploadProgress` snapshot the message carries, so a message that outlives its request -- aborted, `disconnectUser`, rehydrated from an offline store -- stops showing progress instead of spinning forever. That also makes the feature opt-in by construction: an integration that never hands a pending upload to a message has nothing matching a live record, so none of it renders. `AttachmentUploadedSizeIndicator` moves to `Loading/` beside the other upload indicators, and `UploadProgressIndicator` gains `uploadConfirmationPending` -- browser progress reaches 100% when the last byte is written, not when the server answers, so a determinate bar parked at 100% claims something that is not yet true. `RemoveAttachmentPreviewButton` gains a cancel-upload affordance. The settling itself is not here: it moved into stream-chat, behind the `attachments.pendingUploadsEnabled` composer config, so every UI SDK gets the same behaviour. Shared helpers (`resolveAttachmentFileSize`, `resolveAttachmentFullByteSize`) moved there with it. This branch therefore needs a stream-chat carrying that change. Also: `DialogAnchor` gains `closeOnEscape`, and the vite example gets a Composer settings tab with a harness that can slow uploads down or make them fail, which is the only way to reach these states from the UI. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
`RetrySendMessageWithLocalUpdateParams` no longer exists: GetStream/stream-chat-js#1882 replaced the per-operation parameter types with a single `OperationParams<K>`, so `useRetryHandler` takes `Omit<OperationParams<'retry'>, 'message'>` - what `retrySendMessageWithLocalUpdate` now declares. `MessageComposer.send()` resolves `'sent' | 'nothing-to-send' | 'failed'` rather than a boolean (GetStream/stream-chat-js#1881). The poll creation dialog tested the result for truthiness, so a failed send announced "Poll sent" next to its own error notification - every outcome is a truthy string. It compares against `'sent'` now. Nothing else read the boolean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
# Conflicts: # src/components/MessageComposer/AttachmentPreviewList/FileAttachmentPreview.tsx # src/context/ComponentContext.tsx
|
Size Change: +7.15 kB (+0.85%) Total Size: 845 kB 📦 View Changed
ℹ️ View Unchanged
|
The vite example's German and Italian dictionaries are exhaustive and assert it at compile time, so they broke when `messageComposer.sendMessageFn.sendMessageRequestFailed.text` and `messageComposer.updateMessageFn.editMessageRequestFailed.text` gave way to `notification.messageSendFailed` and `notification.messageUpdateFailed`. Same copy, new keys. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`MessageResponse.cid` is required on the wire, but four `message.new` fixtures omitted it. The message paginator matches ingested items on `cid`, so it rejected every one of them and ingested nothing. This went unnoticed because rc.12's `ingestItem` wrote the item into the index regardless of the filter, and the assertion only read the index back - the message was never in `state.items` either way, so the test passed while claiming something untrue. Its three siblings assert negatives, so they passed whatever happened. GetStream/stream-chat-js#1876 stopped writing filter-mismatched items, because a shared entity store must not link an owner to entities it does not hold, and the assertion started failing on rc.13. The fixtures were always wrong; the tightening is what surfaced it. The assertion now also checks the rendered window, which is what the test says it verifies. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## release-v15 #3295 +/- ##
==============================================
Coverage ? 85.39%
==============================================
Files ? 528
Lines ? 15552
Branches ? 4914
==============================================
Hits ? 13280
Misses ? 2272
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
The source moved onto `OperationParams` and `MessageComposer.send`/`update`, both of which arrived in 10.0.0-rc.13, but only the devDependency was bumped. A consumer pinned to rc.12 still satisfied `^10.0.0-rc.12` and broke at build time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ports #3277 onto v15. A message can now carry attachments whose uploads are still in flight: it appears in the list immediately, rendering the local preview with live progress, and resolves in place as the uploads settle.
The progress UI reads
client.uploadManagerrather than the frozenlocalMetadata.uploadProgresssnapshot the message carries, so a message that outlives its request -- aborted,disconnectUser, rehydrated from an offline store -- stops showing progress instead of spinning forever. That also makes the feature opt-in by construction: an integration that never hands a pending upload to a message has nothing matching a live record, so none of it renders.AttachmentUploadedSizeIndicatormoves toLoading/beside the other upload indicators, andUploadProgressIndicatorgainsuploadConfirmationPending-- browser progress reaches 100% when the last byte is written, not when the server answers, so a determinate bar parked at 100% claims something that is not yet true.RemoveAttachmentPreviewButtongains a cancel-upload affordance.The settling itself is not here: it moved into stream-chat, behind the
attachments.pendingUploadsEnabledcomposer config, so every UI SDK gets the same behaviour. Shared helpers (resolveAttachmentFileSize,resolveAttachmentFullByteSize) moved there with it. This branch therefore needs a stream-chat carrying that change.Also:
DialogAnchorgainscloseOnEscape, and the vite example gets a Composer settings tab with a harness that can slow uploads down or make them fail, which is the only way to reach these states from the UI.