Conversation
This was referenced Oct 5, 2026
The transport and storage half of chat photos, ported from code-ios-app#959. Nothing in the app calls it yet; the UI follows in a stacked PR. - Encoding: photos are downscaled and encoded as JPEG down a quality ladder of 0.9, 0.8, 0.7, 0.6 until they fit the blob policy, with EXIF orientation baked in and a BlurHash for the placeholder. The chat_media.json vectors are the iOS file, byte for byte. - Encrypted chats: the blob is sealed with the shared-core ChatCipher, uploaded with the `chat` field, and sent as EncryptedContent. A photo that can't be opened loads as ChatPhotoUnavailable. - Sending: one message per photo, each retried on its own. Finalization polls GetBlobs every 2s, at most 30 times, counted only while the app is in the foreground. - Storage: pending uploads live in Room (schema 43) with the JPEG in filesDir, so a send resumes after the app is killed. - Loading: a Coil fetcher keyed `chat-media-<blobId>`, registered in FlipcashApp. - Fixes found on the way: captions were never sent, because `caption` inside the builder's `apply` resolved to the builder's own field; and a sent message disappeared when the stream delivered its stored copy before the send returned, because clearing the pending row deleted by its client id.
bmc08gt
force-pushed
the
feat/chat-media-transport
branch
from
October 6, 2026 00:58
37fc323 to
cca6d0b
Compare
A photo that finished uploading while it sat in the composer confirms within about 100 ms of the tap. Room hasn't drawn the pending row by then, so the bubble's first frame already reads Sent and the bar never shows. On the Seeker the new bubble landed as Delivered with no bar in any frame. The Sent stage now waits until 800 ms after the row was inserted. The message is still confirmed in the database at once; only the bar's phase waits, and a later post in the same batch isn't held up.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The transport and storage half of chat photos, ported from
code-ios-app#959. Nothing in the app calls it yet; the UI follows in a
stacked PR.
ladder of 0.9, 0.8, 0.7, 0.6 until they fit the blob policy, with EXIF
orientation baked in and a BlurHash for the placeholder. The
chat_media.json vectors are the iOS file, byte for byte.
uploaded with the
chatfield, and sent as EncryptedContent. A photothat can't be opened loads as ChatPhotoUnavailable.
polls GetBlobs every 2s, at most 30 times, counted only while the app
is in the foreground.
filesDir, so a send resumes after the app is killed.
chat-media-<blobId>, registered inFlipcashApp.
captioninside the builder's
applyresolved to the builder's own field; anda sent message disappeared when the stream delivered its stored copy
before the send returned, because clearing the pending row deleted by
its client id.
First of three stacked PRs for chat photos (port of code-payments/code-ios-app#959). Next: the composer layout, then the photo UI.