Skip to content

fix(mobile): iPhone chat pictures were empty gray boxes - #9087

Closed
michaelmonetized wants to merge 1 commit into
pingdotgg:mainfrom
michaelmonetized:fix/ios-chat-images
Closed

michaelmonetized wants to merge 1 commit into
pingdotgg:mainfrom
michaelmonetized:fix/ios-chat-images

Conversation

@michaelmonetized

@michaelmonetized michaelmonetized commented Sep 1, 2026 •

Copy link
Copy Markdown

What Changed

Pictures in iPhone chat were empty gray boxes.

The phone was trying to open a computer file path like media/shots/poster.png as if that file already lived on the phone. It does not. So you got a blank box with the caption under it.

This change:

  1. Hands those pictures to the same signed-url loader the rest of the app already uses.
  2. Stops iOS from treating a workspace path as a download URL.
  3. Loads the real picture with expo-image instead of hiding a React Native Image at opacity 0 (iOS often never paints that).

Why

A real thread looked like this:

IMG_2117

Web can ask the T3 server for that file. The iPhone was skipping that step and drawing an empty 16:9 box.

UI Changes

Before: chat pictures on iPhone are empty rounded gray rectangles. The caption still shows.

After: the phone asks the server for the picture, then draws it.

IMG_2135

I could not take an after screenshot here. This machine has no iOS Simulator. The tests cover the path (media/shots/poster.png is a workspace file, and those image paragraphs stay in the rich markdown chunk the host renderer owns).

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • [!] I included a video for animation/interaction changes

Built with Grok 4.6 in T3 Code.


Note

Low Risk
Scoped to iOS markdown image rendering and thread list refresh keys; no auth or data-model changes, with regression tests added.

Overview
Fixes empty gray image placeholders in iPhone chat when markdown uses workspace-relative paths (e.g. media/shots/poster.png) instead of direct URLs.

On iOS native markdown, renderImage is threaded from SelectableMarkdownText through NativeMarkdownBlock so the thread feed’s signed-URL renderer runs for images in lists, blockquotes, and mixed paragraphs—not only via context. The fallback Image path is restricted to http(s), data, blob, and protocol-relative URLs; other hrefs show an explicit “Image unavailable” placeholder instead of a broken 16:9 box.

In the thread feed, markdown image loading switches to expo-image (with disk cache) and drops the opacity-0 loading trick that often never painted on iOS. LegendList extraData now includes environmentId and workspaceRoot so rows refresh when workspace image resolution changes.

Tests cover workspace image paragraphs staying in rich markdown chunks and classifyMarkdownImageSource behavior for nested workspace paths vs blocked bare paths.

Reviewed by Cursor Bugbot for commit 3b357f6. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fix empty gray image boxes in iPhone chat by switching to expo-image and propagating renderImage

  • Replaces React Native Image with expo-image in ThreadMarkdownImageRequest (ThreadFeed.tsx), setting cachePolicy to memory-disk and contentFit to contain. The image renders at full opacity with a loading overlay instead of being hidden during load.
  • Adds an optional renderImage prop that flows through NativeMarkdownBlock, NativeMixedParagraph, NativeList, NativeMarkdownImage, and SelectableMarkdownText so the host can control image rendering (NativeMarkdownBlock.ios.tsx).
  • Introduces DIRECT_MARKDOWN_IMAGE_HREF_PATTERN to block non-direct hrefs (anything not http(s), data, blob, or protocol-relative) in the fallback Image path; those now render a placeholder labeled "Image unavailable".
  • Risk: Images with non-direct hrefs that previously attempted (and failed) to load now render a placeholder unless a custom renderImage handles them. ThreadFeed adds environmentId and workspaceRoot to listAppearanceData extraData, so rows depending on those values re-render on change.

Macroscope summarized 3b357f6.

Chat markdown like ![Poster](media/shots/poster.png) was handed to iOS
Image as a relative path. The phone cannot load files off the host
machine that way, so users got empty boxes.

Pass the app image renderer into the iOS markdown tree, skip Image for
workspace paths, and load signed asset URLs with expo-image.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Sep 1, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This is a focused iOS image bug fix, but it also propagates the host renderer into existing rich-markdown paths, activating signed workspace-asset resolution, caching, previews, and a new native image-loading path. That production behavior change is non-trivial enough to warrant human review.

You can add or adjust custom eligibility rules. Learn more.

Copy link
Copy Markdown
Member

Note

This comment is posted by Julius' dot

The second image shows loaded pictures, but the description says an after screenshot could not be captured without an iOS Simulator. Which client and PR build produced that image, and was the changed iOS rendering path exercised? Please report the focused test commands and results too, so the supplied verification can be matched to this fix.

@maria-rcks

Copy link
Copy Markdown
Collaborator

Note

Written by claude-opus-5-5 on behalf of Maria

Hi! We are cleaning up open PRs, and this one appears to have been created with an older model (grok 4.6). If this change is really important, we recommend rebuilding the PR with a newer model if possible.

@maria-rcks maria-rcks closed this Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants