Skip to content

fix(mobile): respect prose direction in chat and composer - #23587

Open
haithamassoli44 wants to merge 3 commits into
pingdotgg:mainfrom
haithamassoli:fix/mobile-bidi-text
Open

haithamassoli44 wants to merge 3 commits into
pingdotgg:mainfrom
haithamassoli:fix/mobile-bidi-text

Conversation

@haithamassoli44

@haithamassoli44 haithamassoli44 commented Oct 22, 2026 •

Copy link
Copy Markdown

Problem

Mobile still resolves mixed prose from its first letter, even after #22777 fixed web and desktop. In StrictMode: يعيد العرض مرتين في التطوير, the English prefix makes the Arabic paragraph LTR. Inline fetch() reads as ()fetch, and RTL quote borders stay on the left. The same failure is reproducible in Hebrew.

Change

Use #22777's word-majority rule in the shared native Markdown renderer and the native chat/new-thread composers. Ties follow the first word; code and chips do not vote.

  • The pinned Enriched renderer gets an opt-in word-majority mode for iOS and Android. Lists and quotes share their block's direction; table cells resolve independently. Inline and fenced rendered code stay LTR.
  • Native composer direction is presentation metadata. Source text, UTF-16 selection offsets, chips, marked text and undo handling stay on their existing paths.
  • Tagged display controls are removed during plain-text, HTML, Markdown and custom-action export. Authored bidi marks are preserved.
  • Explicit table alignment remains physical left/right, independently of cell direction. Table column order keeps its existing behavior.

Scope and approval

Native follow-up to merged #22777 and the RTL rendering problem in #13622. The current native integration gap was also documented in the #16839 preflight. This uses the word policy already merged for web rather than introducing another direction heuristic.

The shared renderer covers user/assistant messages, review/PR Markdown and Markdown file previews. Composer changes cover chat and new-thread drafts. Provider adapters, server contracts and connection modes carry the same source text.

Verification

Rebuilt and verified matching native development clients on iPhone 18 Pro / iOS 27.0 and an Android 16 / API 36 emulator using node scripts/mobile-native-client.ts ensure ... and a final check on each platform.

Matched captures show English-led Arabic/Hebrew headings and paragraphs resolving RTL, inline fetch() retaining its order, quote borders on the right, and English/fenced code remaining LTR. The recordings exercise typing and a transition from an Arabic paragraph to an English paragraph. On Android, selected rich text containing inline code was copied and pasted into the composer; source prose/code remained intact without synthesized bidi controls.

  • vp run check:changed passed: format, lint, knip and typecheck of the 32 impacted packages. The dependency patch/lockfile expand this command's impact automatically.
  • bash apps/mobile/modules/t3-composer-editor/tests/check-text-direction.sh passed 15 word-vote cases, 12 documents, and UTF-16/trailing-line checks.
  • From apps/mobile/android: ./gradlew :t3-composer-editor:testDebugUnitTest --tests expo.modules.t3composereditor.ComposerTextDirectionTest :react-native-enriched-markdown:testDebugUnitTest --tests com.swmansion.enriched.markdown.utils.text.view.DirectionClipboardTest passed 12 tests: 5 composer and 7 renderer/clipboard cases. These include actual Android span/layout APIs, multiline code extraction, authored marks, HTML, explicit table alignment and preservation of RTL-locale column order.
  • Objective-C word-direction/AST/clipboard self-checks passed 11 direction cases plus block inheritance and independent tables. Focused source harnesses reproduced the export/alignment review bugs before their fixes and passed afterward. Added iOS XCTest regressions were syntax checked; a full XCTest target was not executed.
  • Targeted SwiftLint, ktlint and detekt passed for the changed composer sources/tests. The dependency patch dry-applies to the exact current archive; all 43 patched files match the verified tree.

Matched native captures

Both sides use the same isolated stopped-conversation fixtures with synthetic Arabic/Hebrew text. These verify client rendering, not a live provider response. Before uses native code from 8d3b061121fe; after uses this branch's rebuilt clients. PR-only assets are hosted on the fork release and are not committed.

Native case Before After
IOS arabic before ios arabic after ios arabic
IOS hebrew before ios hebrew after ios hebrew
IOS composer before ios composer after ios composer
ANDROID arabic before android arabic after android arabic
ANDROID hebrew before android hebrew after android hebrew
ANDROID composer before android composer after android composer

Typing recordings: iOS (31 seconds) · Android (13 seconds).

Limits

The Android plaintext composer receives isolated paragraph buffers: it excludes inline code from word voting, but does not isolate inline-code runs, resolve fence bodies from the whole document, or inherit direction for neutral-only lines. Rendered Markdown uses its AST for code and block direction. Scheduled-task prompts and review-comment inputs keep their existing native text-input behavior. Physical devices, hardware-keyboard editing, IME composition/cancellation and undo/redo were not checked.

Implemented with GPT-6.1 Sol using the Codex harness in T3 Code.

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

macroscopeapp Bot commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — This PR introduces broad Android/iOS Markdown rendering and composer direction behavior, activates a 1,665-line production dependency patch, and changes the mobile Markdown component’s effective direction default. The resulting cross-platform regression surface is substantially larger than a self-contained bug fix.

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

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⛔ Files ignored due to path filters: 1
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between 1da551a and 7c7db8c.

⛔ Files ignored due to path filters: 1
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between 8d3b061 and 1da551a.

⛔ Files ignored due to path filters: 1
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing: 10
  • apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/ComposerTextDirection.kt
  • apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ComposerEditorView.kt
  • apps/mobile/modules/t3-composer-editor/android/src/test/java/expo/modules/t3composereditor/ComposerTextDirectionTest.kt
  • apps/mobile/modules/t3-composer-editor/ios/ComposerTextDirection.swift
  • apps/mobile/modules/t3-composer-editor/ios/T3ComposerEditorView.swift
  • apps/mobile/modules/t3-composer-editor/tests/ComposerTextDirectionCheck.swift
  • apps/mobile/modules/t3-composer-editor/tests/check-text-direction.sh
  • apps/mobile/src/native/EnrichedMarkdownText.tsx
  • patches/react-native-enriched-markdown@1.2.0-t3.15.patch
  • pnpm-workspace.yaml

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📝 Walkthrough

The mobile composer now detects and applies paragraph direction on Android and iOS. The enriched Markdown component enables word-majority direction, which the patched native renderers use for Markdown blocks, tables, code, and output cleanup.

Changes: Mobile word-majority direction

Layer / File(s) Summary
Composer paragraph direction
apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/ComposerTextDirection.kt, apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ComposerEditorView.kt, apps/mobile/modules/t3-composer-editor/android/src/test/java/expo/modules/t3composereditor/ComposerTextDirectionTest.kt, apps/mobile/modules/t3-composer-editor/ios/ComposerTextDirection.swift, apps/mobile/modules/t3-composer-editor/ios/T3ComposerEditorView.swift, apps/mobile/modules/t3-composer-editor/tests/*
Android and iOS classify paragraph direction by the first letter in each word. The editor applies direction to paragraphs and typing attributes, while code ranges remain left-to-right. Tests check direction votes, code handling, and UTF-16 offsets.
Markdown mode and direction annotation
apps/mobile/src/native/EnrichedMarkdownText.tsx, patches/react-native-enriched-markdown@1.2.0-t3.15.patch, pnpm-workspace.yaml
The mobile component sets writingDirection to word-majority. The patch adds the mode to native prop handling, annotates Markdown structures for rendering and measurement, and updates the TypeScript prop type.
Native direction-aware rendering
patches/react-native-enriched-markdown@1.2.0-t3.15.patch
Android and iOS apply direction metadata to paragraphs, code, blockquotes, and tables. The renderers add marked controls for code direction and handle direction in link pills.
Generated direction-control cleanup
patches/react-native-enriched-markdown@1.2.0-t3.15.patch
Markdown, HTML, clipboard, and RTF output omit generated direction controls. Added tests cover cleanup, authored directional marks, and table alignment.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~60 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant MobileEnrichedMarkdownText
  participant EnrichedMarkdownText
  participant wordMajorityAST
  participant NativeRenderer
  MobileEnrichedMarkdownText->>EnrichedMarkdownText: Set writingDirection to word-majority
  EnrichedMarkdownText->>wordMajorityAST: Annotate parsed Markdown
  wordMajorityAST->>NativeRenderer: Provide direction metadata
Loading

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to 1da55

This change adds word-majority text direction to mobile Markdown rendering and the composers. No concrete merge-blocking defect was found. Device-level IME and undo/redo testing was not done, as the PR states, but that is not evidence of a defect.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title is concise, uses the expected conventional format, and clearly describes the main mobile prose-direction fix.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The pull request description is complete and follows the required template. It explains the problem, change, scope and approval, verification steps, observed results, UI evidence, limits, and the agen…
Full details: Description check

Explanation

The pull request description is complete and follows the required template. It explains the problem, change, scope and approval, verification steps, observed results, UI evidence, limits, and the agent and harness used.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@haithamassoli44

Copy link
Copy Markdown
Author

@Yash-Singh1

@Yash-Singh1 Yash-Singh1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This works well, but I am hesitant to bringing in such a large patch to enriched-markdown, would you be willing to open up PRs to upstream some of these patches to their repo?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ 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.

2 participants