Skip to content

fix(mobile): match browser GIF timing in the iOS reaction sheet - #9437

Merged
brow merged 1 commit into
mainfrom
gif-timing-followups
Nov 13, 2026
Merged

brow merged 1 commit into
mainfrom
gif-timing-followups

Conversation

@brow

@brow brow commented Nov 13, 2026 •

Copy link
Copy Markdown
Collaborator

The two follow-ups from the pre-review of #9432 GIF frame timing, rebased onto main now that it has landed.

iOS reaction details sheet. The sheet decodes custom emoji natively (NativeMessageImageLoader.decode) and timed each frame as max(0.02, delay), so with #9432 GIF frame timing a GIF with 0 or 1 cs delays plays at 100 ms per frame in the timeline chip but 20 ms per frame in the sheet opened from it. The decoder now shows frames of 10 ms or less for 100 ms, as browsers and MediaImageProvider do, and keeps longer frames as written. The 20 ms floor goes with it: browsers keep 11 to 19 ms frames as written too.

Provider-level test. The existing tests call withBrowserFrameTiming directly, so removing the provider's call to it left the suite green. A new test resolves a GIF through MediaImageProvider with a mock HTTP client and pumps the scheduler's app frames at explicit timestamps: the 10 ms first frame is still showing at 50 ms and is replaced at 100 ms.

Regressions

None expected. The sheet already summed the frame delays into one UIImage.animatedImage duration, so only the per-frame value changes, and only for frames of 10 ms or less, which ran at 20 ms before. Still images and longer frames decode as before. The Dart test drives frame callbacks with explicit timestamps rather than waiting on wall-clock time.

Validation

Added tests: NativeMessageImageLoaderDecodeTests in RunnerTests (a 0, 1, 2, 5 cs GIF decodes to a 0.27 s animation; a one-frame GIF stays still) and withBrowserFrameTiming is applied to the frames MediaImageProvider plays in media_image_test.dart, which fails when the provider's call is removed (the second frame shows at 50 ms).

Full mobile suite: 4,780 tests passed. flutter analyze: no issues. RunnerTests NativeMessageImageLoaderDecodeTests and NativeReactionDetailsTests: all five pass on an iPhone 17 simulator (Xcode build-for-testing of the Debug simulator app). No full-app run: the change is one delay value in a decoder and is covered by the unit tests above.

@brow
brow marked this pull request as ready for review November 13, 2026 01:34
@brow
brow requested a review from a team as a code owner November 13, 2026 01:34
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-13T01:35:40.149019Z 4bf446c Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Base automatically changed from peon/mobile-gif-min-frame-delay to main November 13, 2026 01:43

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

🤖 Approved (code-only review).

No defects found.

  • NativeReactionDetails.swift: ImageIO reports UnclampedDelayTime 0 / 0.01 / 0.02 / 0.05 for a 0/1/2/5 cs GIF (checked with a standalone ImageIO script), so delay <= 0.01 ? 0.1 : delay gives 0.27 s, matching the Dart withBrowserFrameTiming rule and the new XCTest. Dropping the 0.02 floor changes only frames of 10 ms or less, which now use 100 ms.
  • Provider test: withBrowserFrameTiming tests pass locally (3/3). With the provider call reverted to return await decode(buffer);, the new provider test fails, so it guards the wiring as described.

Merge blocker (not code): the PR is CONFLICTING because the branch still carries the pre-squash commit from #9432. Rebase onto main and drop that commit, so the diff is just the Swift change plus the tests. The description still says the PR targets the #9432 branch; the base is now main.

Not run here: the RunnerTests XCTests (Mobile Swift CI was still pending).

The reaction details sheet decodes custom emoji natively and showed
frames of 10 ms or less for 20 ms, while the Flutter timeline (with the
short-delay clamp in MediaImageProvider) shows them for 100 ms, so the
same emoji played five times faster in the sheet than in the chip that
opened it. Map such frames to 100 ms there too, and drop the 20 ms
floor, which browsers do not have.

Also cover the provider's use of the clamp: a GIF resolved through
MediaImageProvider keeps its 10 ms first frame on screen for 100 ms.

Signed-off-by: Tom Brow <[email protected]>
Co-authored-by: judge <7615ec4b7ddf99f0bb48e913297f99f8f772d289a1c9ef54e1d906dd55a93ba8@sprout-oss.stage.blox.sqprod.co>
@brow
brow force-pushed the gif-timing-followups branch from 4bf446c to 9c15fba Compare November 13, 2026 01:52
@brow
brow deployed to codex-review November 13, 2026 01:52 — with GitHub Actions Active
@github-actions github-actions Bot added the codex-security-review-current The posted Codex security review matches its recorded range. label Nov 13, 2026
@github-actions

Copy link
Copy Markdown

🔐 Codex Security Review

Note: This is an automated, security-focused review generated by Codex.
Use it as a supplement to human review; false positives are possible.

Scope

  • Exact PR diff: 0bbcf3e7c24c6bb46a4bd3f5fd7fb94aa391a3f3...9c15fbadd845b82a881beef3a0a218e59af51dfe
  • Model: gpt-6.1-sol

💡 Click "edited" above to see earlier reviews for this PR.


Review Summary

Overall Risk: NONE

No concrete security, correctness, or reliability regressions found in the authorized PR range.

Findings

No concrete security, correctness, or reliability findings were identified.

Notes

  • Review used read-only source and history inspection. Builds and tests were not executed, as instructed.

Generated by Codex Security Review |
Requested by: @brow |
Workflow run

@brow
brow enabled auto-merge (squash) November 13, 2026 01:58
@brow
brow merged commit bf3bdd0 into main Nov 13, 2026
52 checks passed
@brow
brow deleted the gif-timing-followups branch November 13, 2026 02:01
bostonaholic added a commit that referenced this pull request Nov 13, 2026
Co-authored-by: mboston.Engineer <932d3b6ebea6cc83e091551ae46d1c7e7f8f7d0fa8e9cef5e6facc8544af413b@buzz.block.builderlab.xyz>

* origin/main:
  fix(mobile): require Builderlab consent for existing identities (#8823)
  feat(mobile): use HTTP/2 on iOS through app-wide URLSessions (#8897)
  fix(relay): publish a git push only when refs changed; check the protocol by refinement (#9425)
  fix(mobile): show shared chats under Solo (#9348)
  chore(release): release Buzz Desktop version 0.5.29 (#9456)
  feat(mobile): render messages with gpt_markdown 1.3.4 plusparse (#8945)
  fix(acp): bound observer retention by bytes (#7987) (#9436)
  Tune release codegen for faster/smaller binaries (#9434)
  feat(desktop): add dismissible banner pointing to the new buzz app (#9379)
  fix(mobile): keep publishing presence while the app is open (#9441)
  feat(mobile): share into Buzz from the iOS share sheet (#9433)
  fix(mobile): qualify every namesake mention and keep authored mention casing (#9325)
  fix(mobile): match browser GIF timing in the iOS reaction sheet (#9437)
  fix(mobile): play short-delay animation frames at browser speed (#9432)
  buzz-search: read profile names without the profile_name_fields function (#9397)
  buzz-db: build the community deletion lock key in Rust (#9396)
  fix(cli): pair for the active community, skip stopped desktops, accept a bare relay host (#9417)
  test(mobile): run push tests without a gateway dart-define (#9423)
  fix(mobile): never pop Home when archiving from channel settings (#9387)
  perf(acp): reduce observer CPU and lock overhead (#9381)

Signed-off-by: Matthew Boston <[email protected]>
bostonaholic added a commit that referenced this pull request Nov 13, 2026
…count-backfill

Co-authored-by: mboston.Engineer <932d3b6ebea6cc83e091551ae46d1c7e7f8f7d0fa8e9cef5e6facc8544af413b@buzz.block.builderlab.xyz>

* bostonaholic--agent-reply-count:
  fix(mobile): require Builderlab consent for existing identities (#8823)
  feat(mobile): use HTTP/2 on iOS through app-wide URLSessions (#8897)
  fix(relay): publish a git push only when refs changed; check the protocol by refinement (#9425)
  fix(mobile): show shared chats under Solo (#9348)
  chore(release): release Buzz Desktop version 0.5.29 (#9456)
  feat(mobile): render messages with gpt_markdown 1.3.4 plusparse (#8945)
  fix(acp): bound observer retention by bytes (#7987) (#9436)
  Tune release codegen for faster/smaller binaries (#9434)
  feat(desktop): add dismissible banner pointing to the new buzz app (#9379)
  fix(mobile): keep publishing presence while the app is open (#9441)
  feat(mobile): share into Buzz from the iOS share sheet (#9433)
  fix(mobile): qualify every namesake mention and keep authored mention casing (#9325)
  fix(mobile): match browser GIF timing in the iOS reaction sheet (#9437)
  fix(mobile): play short-delay animation frames at browser speed (#9432)
  buzz-search: read profile names without the profile_name_fields function (#9397)
  buzz-db: build the community deletion lock key in Rust (#9396)
  fix(cli): pair for the active community, skip stopped desktops, accept a bare relay host (#9417)
  test(mobile): run push tests without a gateway dart-define (#9423)
  fix(mobile): never pop Home when archiving from channel settings (#9387)
  perf(acp): reduce observer CPU and lock overhead (#9381)

Signed-off-by: Matthew Boston <[email protected]>

This branch was successfully deployed

1 active deployment
codex-review — 9c15fbad Deployed Nov 13, 2026 by brow via Run Codex Security Review #14790
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codex-security-review-current The posted Codex security review matches its recorded range.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants