Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(site/src/pages/AgentsPage): stop attachment downloads from trapping iOS PWAs - #27853

Merged
ibetitsmike merged 43 commits into
mainfrom
mike/fix-ios-pwa-attachment-download
Aug 12, 2026
Merged

fix(site/src/pages/AgentsPage): stop attachment downloads from trapping iOS PWAs#27853
ibetitsmike merged 43 commits into
mainfrom
mike/fix-ios-pwa-attachment-download

Conversation

@ibetitsmike

@ibetitsmike ibetitsmike commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

On iOS, tapping an attachment download link inside the installed (standalone) PWA hands the file to QuickLook, which renders on top of the app with no reliable way back. Users had to force-quit the PWA to recover.

Approach

In iOS standalone mode, when the device supports file sharing, the download click is intercepted and the fetched attachment is handed to the native share sheet (navigator.share with a File), where the user can pick Save to Files or any other target. This is the platform-intended path for saving files from a PWA; no library covers it (FileSaver.js is broken in iOS PWAs, and browser-fs-access falls back to the same broken anchor path).

Everything else keeps native behavior:

  • Non-iOS platforms and regular iOS Safari tabs keep the plain <a download> anchor.
  • iOS standalone devices without file sharing keep the anchor too.
  • Inline data: attachments are decoded locally because the production CSP (connect-src 'self') blocks fetching them.

Error model

Deliberately small: a share-sheet dismissal (AbortError) is silent, an expired click gesture (NotAllowedError, which happens when the fetch outlasts transient activation) shows a toast whose Save action retries with a fresh gesture, and any other failure shows a plain error toast.

An earlier revision carried pending-state tracking, abort-signal threading through unmount, and a blob-URL tab fallback; those guards were removed on purpose to keep the change proportionate to the defect.

Also hardens chat file uploads slightly: filenames are sanitized before upload and the file-picker accept attribute mirrors the server's attachment allowlist.

Testing

  • Storybook interaction tests cover the share happy path and native-anchor behavior; unit tests cover the intercept gate (including iPadOS detection), failure toasts, retry action, and inline-data decode.
  • Validated on an iPhone against a dev deployment: share sheet opens, Save to Files works, and the app remains usable afterwards.

Mux implemented this on Mike's behalf.

…ng iOS PWAs

iOS home-screen web apps open <a download> targets in a QuickLook
preview that has no dismiss chrome, so tapping the download icon on a
chat attachment locked the app until it was killed. Intercept those
clicks and hand the file to the native share sheet instead, falling
back to a dismissible in-app browser tab when file sharing is
unavailable. Other platforms keep the native anchor download.
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@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.

@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@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.

@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4354e9bd50

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/components/ChatConversation/AttachmentBlocks.tsx Outdated
…eption in Storybook

Adds play interactions for the share-sheet path, the no-share fallback
tab, and the untouched native anchor outside iOS.
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7546235e98

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts Outdated
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6ed7b29a30

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts Outdated
…ad failures

After the iOS standalone handler prevents the anchor's native action,
a failed fetch or share left the user with no feedback. Show an error
toast instead of only logging to the console.
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 88157eff3d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts Outdated
…before share

A slow attachment fetch can outlive iOS's transient user activation,
making navigator.share reject with NotAllowedError after the native
anchor action was already prevented. Keep the fetched file and offer
a Save action on the error toast; the action click is a fresh gesture,
so retrying from it succeeds.
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6baa5cb6bd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts Outdated
…tivation

A Save action on other share rejections would fail identically on
every click; keep it only for NotAllowedError.
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 54d31898b5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts
Comment thread site/src/pages/AgentsPage/utils/chatAttachments.test.ts Outdated
…rendered toast

Clicks the real toast action in a Storybook play instead of invoking
the callback with a cast stand-in event in the unit test.
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: 39b8727e48

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: e5798239ca

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

… download extension

iOS resolves the shared or saved file's type from the filename
extension, so sharing an image named "About Page Screenshot" landed
in the share sheet as a generic file with no Save Image option.
Append the media-type-derived extension when the name lacks one.
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a306915abf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts
Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts Outdated
…-sheet core

Drop the pending-state wiring, abort-signal threading, and the blob-URL
tab fallback. iOS standalone now shares via the share sheet when file
sharing is available and keeps the native anchor otherwise. Failures
surface one toast, with a Save retry after expired activation.
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

Mux acted on Mike's behalf. The implementation was reduced to a share-sheet core per Mike's direction: the pending-state guards, abort threading, and tab fallback were removed deliberately to keep the diff proportionate. Please review the current head.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: 187f34405c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike
ibetitsmike marked this pull request as ready for review August 11, 2026 15:41

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 187f34405c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts
Comment thread site/src/pages/AgentsPage/utils/dataUrls.ts
Comment thread site/src/pages/AgentsPage/components/ChatConversation/AttachmentBlocks.tsx Outdated
Comment thread site/src/pages/AgentsPage/components/ChatConversation/AttachmentBlocks.tsx Outdated
Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts Outdated
Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts Outdated
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d9d7b7bc13

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts Outdated
Comment thread site/src/pages/AgentsPage/utils/dataUrls.ts
Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts
Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts Outdated
Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts Outdated
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a2e88ea95b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/utils/chatAttachments.ts
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: 65454a0ddd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 65454a0ddd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike
ibetitsmike merged commit ac11ae5 into main Aug 12, 2026
26 checks passed
@ibetitsmike
ibetitsmike deleted the mike/fix-ios-pwa-attachment-download branch August 12, 2026 06:31
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants