Skip to content

fix(web): materialize Android picker images on selection - #122

Merged
wolfiesch merged 7 commits into
LycaonLLC:mainfrom
brainage04:fix/android-picker-attachment-materialization
Jul 21, 2026
Merged

fix(web): materialize Android picker images on selection#122
wolfiesch merged 7 commits into
LycaonLLC:mainfrom
brainage04:fix/android-picker-attachment-materialization

Conversation

@brainage04

Copy link
Copy Markdown
Contributor

Summary

  • read every selected image immediately while Android's picker-backed content grant is still live
  • magic-sniff those bytes and stage a renderer-owned File for previews and later upload
  • serialize attachment admission and prevent send/queue actions while a selection is being prepared
  • retain per-file rejection messages without discarding successfully materialized siblings

Reproduction

On a Samsung Android device, selecting a valid JPEG through the system Photo Picker produced a transient content-provider File. The attachment chip could be created from its metadata, but the later upload read failed with NotReadableError, surfacing:

One of the attached files is not a readable PNG, JPEG, WebP, or GIF image.

The file was a valid baseline JPEG; the failure was the lifetime of the picker-backed File, not .jpg format support.

Verification

  • pnpm check
  • pnpm test
  • focused composer/image-upload tests: 37 passed
  • Android picker regression: verifies FileReader starts synchronously, bypasses a later-failing source arrayBuffer(), and stages a distinct byte-backed JPEG File
  • browser demo smoke test at Android viewport: attached a real JPEG, observed its preview/chip, sent the prompt, and observed the accepted message with the draft and chip cleared

@brainage04
brainage04 force-pushed the fix/android-picker-attachment-materialization branch from 84ac38e to 7507c76 Compare July 21, 2026 07:36

@oleksoleksoleks oleksoleksoleks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two merge blockers:

  1. Pending materialization can revive a deleted session. disposeSession clears current attachments, but an already queued FileReader later calls addAttachments(sessionId, result.accepted), recreating hidden state and preview URLs with no disposal path. Invalidate pending intake with a session lifetime token before admission.

  2. Concurrent picker/paste/drop batches bypass the global staging cap because each snapshots only admitted attachments before allocating every FileReader buffer. Reserve byte/count capacity before materialization, or serialize all intake so pending batches count toward the cap.

Applicable CI is green, but these lifecycle and bounded-memory invariants need tests and fixes before merge.

@wolfiesch

Copy link
Copy Markdown
Collaborator

Thanks for the PR. I added a small follow-up:

  • enforce attachment count and size limits before starting FileReader
  • avoid materializing duplicate source files
  • add regression coverage for prompt and global staging limits

@oleksoleksoleks

Copy link
Copy Markdown
Contributor

Implemented session-lifetime invalidation and serialized global attachment intake, rebased the complete contribution onto current main, and opened #133 as the replacement. Web typecheck and all 1,219 tests pass. Please close this superseded branch.

@wolfiesch
wolfiesch merged commit ba5783a into LycaonLLC:main Jul 21, 2026
11 checks passed
@brainage04
brainage04 deleted the fix/android-picker-attachment-materialization branch July 21, 2026 23:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants