Skip to content

fix(mobile): correct Arabic RTL alignment and duplicate free badge - #6636

Merged
iscekic merged 7 commits into
mainfrom
kwf/explorer-4-visual-defects-on-ios-in-the-single-arabic-sea-8d9f3-5aa7
Sep 25, 2026
Merged

iscekic merged 7 commits into
mainfrom
kwf/explorer-4-visual-defects-on-ios-in-the-single-arabic-sea-8d9f3-5aa7

Conversation

@iscekic

@iscekic iscekic commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Changelog for users

  • In a right-to-left interface, the repository and model picker search fields keep the typed query and its placeholder on the same edge as the clear and search controls.
  • In a left-to-right interface, an Arabic language row's endonym and its English subtitle share one alignment edge.
  • A model whose title already states it is free no longer repeats the fact with a second green badge, and a screen reader no longer hears it twice.
  • Settings no longer shows the developer feature-flag rows, so no English "default" or "not loaded" string sits inside a translated row.

Changelog for maintainers

  • modelNameStatesFree(name, displayId) reports that a displayed name already states free when it carries the catalogue's (free) marker, contains the localized free label, or resolves to the kilo-auto/free model after prefix stripping.
  • Model picker rows drop both the green free badge and its accessibility phrase when the name already states free; BYOK and data-collection badges are unchanged.
  • Language picker rows add text-left to both lines only in an LTR interface; RTL keeps the paragraph direction applied by components/ui/text.
  • The repository and model picker search fields render the shared @/components/ui/input, which applies withRtlInputAlignment from lib/rtl-text.ts to every single-line field, so the call sites do not repeat it. Merging main resolved the overlapping edits in favour of that shared contract.
  • The feature-flag half of the reported defects landed on main and is inherited here through the merge: fix(mobile): translate feature-flag row reason copy in every catalog #6585 translated the row reason copy in every catalog, and fix(mobile): remove developer feature-flag rows from Preferences #6609 removed the developer feature-flag rows from Preferences altogether (feature-flags-section.tsx and its test are deleted, so no preferences.featureFlag* key remains).
  • Mounted tests cover the pickers' RTL/LTR style arrays and the badge suppression, including the nine locales whose Auto Free name does not contain the badge label.
  • Review first: the free-badge suppression against catalogue names and the Auto Free identity, then the style arrays asserted in the picker tests.

E2E proof

Device verification did not pass; the iOS bridge round exited rc=1 and is recorded as a follow-up rather than a pass. Shard 1's verdict judged e1 passed (English/LTR language picker: the Arabic row at [14,187][388,243]); no capture accompanied this pack's evidence.

@iscekic
iscekic marked this pull request as draft September 23, 2026 09:32
@kilo-code-bot

kilo-code-bot Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental review of the net 7-file, 245-line diff at HEAD 2ea4c01 (the earlier picker-field changes now match main, so they left the diff): the modelNameStatesFree free-badge suppression, its ModelPickerOptionRow call site, and the LTR text-left alignment on language-picker rows are internally consistent, with the new tests matching the shared @/components/ui/input and text mock contracts.

Files Reviewed (7 files)
  • apps/mobile/src/components/agents/model-selector.tsx
  • apps/mobile/src/components/agents/model-selector.mounted.test.tsx
  • apps/mobile/src/components/agents/picker-search.mounted.test.tsx
  • apps/mobile/src/components/language-picker-row.tsx
  • apps/mobile/src/components/language-picker-sheet.mounted.test.tsx
  • apps/mobile/src/lib/free-model-data-disclosure.ts
  • apps/mobile/src/lib/free-model-data-disclosure.test.ts

Verification Notes

  • modelNameStatesFree(name, displayId) returns true for the gateway (free) marker, the localized free label, or stripModelPrefix(displayId) === 'kilo-auto/free'; all three paths are visible in the row title, so suppressing the badge does not hide the fact.
  • showFreeBadge = free && !byok && !modelNameStatesFree(...) is a strict subset of the prior free || byok || collectsData container condition, so BYOK and data-collection badges still render; only the redundant green badge and its accessibility phrase are dropped.
  • picker-search.mounted.test.tsx asserts withRtlInputAlignment's [{ textAlign: 'right' }, style] array against the shared @/components/ui/input, which is the sole field renderer in both pickers now; the LTR cases match the unchanged-display contract.
  • language-picker-row.tsx adds text-left only when !isRtl; ui/text applies no inline alignment in LTR, so the class is effective and both row lines share one edge.
  • No .md files changed; the changed production code adds only pure calls (no subscriptions, timers, or listeners), so no memory-leak surface is added.
Previous Review Summaries (3 snapshots, latest commit ca02ee5)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit ca02ee5)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Full re-review of the current 10-file, 260-line diff (the previously reviewed SHA is not an ancestor of the current head, so the incremental diff was unusable and the whole diff was reviewed): the RTL input-alignment helper and its repository/model search-field callers, the LTR language-row alignment, and the modelNameStatesFree free-badge suppression are internally consistent and contain no defects.

Files Reviewed (10 files)
  • apps/mobile/src/app/(app)/agent-chat/repo-picker.tsx
  • apps/mobile/src/components/agents/model-picker-content.tsx
  • apps/mobile/src/components/agents/model-picker-content.mounted.test.tsx
  • apps/mobile/src/components/agents/model-selector.tsx
  • apps/mobile/src/components/agents/model-selector.mounted.test.tsx
  • apps/mobile/src/components/agents/picker-search.mounted.test.tsx
  • apps/mobile/src/components/language-picker-row.tsx
  • apps/mobile/src/components/language-picker-sheet.mounted.test.tsx
  • apps/mobile/src/lib/free-model-data-disclosure.ts
  • apps/mobile/src/lib/free-model-data-disclosure.test.ts

Verification Notes

  • withRtlInputAlignment (lib/rtl-text.ts) and stripModelPrefix (lib/model-id.ts) already exist and resolve the new imports; the RTL array [{ textAlign: 'right' }, style] is a valid StyleProp, and LTR returns the caller's style unchanged (undefined for the model picker).
  • showFreeBadge = free && !byok && !modelNameStatesFree(...) is a strict subset of the previous free || byok || collectsData render condition, so the badge container still renders for BYOK/data-collection rows; suppression only drops the redundant green badge and its accessibility phrase.
  • The nine it.each locales (be, bg, bs, hr, mk, ru, sr, ta, uk) all have models.auto.free distinct from models.free, so the badge-suppression assertions are satisfiable; the kilo-auto/free identity check covers them.
  • The current diff contains no locale-catalog or tools/i18n changes (those landed upstream in fix(mobile): translate feature-flag row reason copy in every catalog #6585/fix(mobile): remove developer feature-flag rows from Preferences #6609), so the PR description's catalog/feature-flag changelog entries describe work not present in this diff.
  • No .md files changed; the changed production paths add only pure calls (no subscriptions, timers, or listeners), so no memory-leak surface was added.

Previous review (commit de751ff)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Full re-review of the current PR diff (the prior review SHA is not an ancestor of the current head, so the incremental diff was unusable and the whole diff was reviewed): the RTL input-alignment helper and its search-field callers, the LTR language-row alignment, the modelNameStatesFree free-badge suppression, the feature-flag status translations across the 70 changed non-English catalogs, and the new/updated tests are internally consistent and contain no defects.

Files Reviewed (83 files)
  • apps/mobile/src/app/(app)/agent-chat/repo-picker.tsx
  • apps/mobile/src/components/agents/model-picker-content.tsx
  • apps/mobile/src/components/agents/model-picker-content.mounted.test.tsx
  • apps/mobile/src/components/agents/model-selector.tsx
  • apps/mobile/src/components/agents/model-selector.mounted.test.tsx
  • apps/mobile/src/components/agents/picker-search.mounted.test.tsx
  • apps/mobile/src/components/feature-flags-section.tsx
  • apps/mobile/src/components/language-picker-row.tsx
  • apps/mobile/src/components/language-picker-sheet.mounted.test.tsx
  • apps/mobile/src/i18n/catalog-parity.test.ts
  • apps/mobile/src/lib/free-model-data-disclosure.ts
  • apps/mobile/src/lib/free-model-data-disclosure.test.ts
  • tools/i18n/check-catalogs.mjs
  • apps/mobile/src/i18n/locales/*.json (70 changed non-English catalogs)

Verification Notes

  • withRtlInputAlignment and stripModelPrefix already exist and resolve the new imports; the RTL array [textAlign: 'right', undefined] is a valid React Native StyleProp and the LTR call returns the caller's style unchanged.
  • All three preferences.featureFlag* keys exist in every non-English catalog, retain the {{min}} placeholder where English has one, and differ from English; the keys are no longer on the ENGLISH_IDENTICAL_ALLOWLIST.
  • showFreeBadge is a strict subset of the old free || byok || collectsData render condition and only suppresses the redundant badge and screen-reader phrase when the displayed name or the resolved kilo-auto/free identity already states free.
  • The changed production paths add only pure calls; no subscriptions, timers, or listeners were introduced, so no memory-leak surface was added. No .md files changed.

Previous review (commit 0471c04)

Status: No Issues Found | Recommendation: Merge

Executive Summary

I reviewed the mobile RTL alignment fixes, the free-badge suppression logic, the feature-flag status translations across all 86 non-English catalogs, and the associated tests; the changed lines are internally consistent, the placeholder/$t() invariants hold, and the new i18n checks match the catalogs, so I found no defects in the changed code.

Files Reviewed (94 files)
  • apps/mobile/src/app/(app)/agent-chat/repo-picker.tsx
  • apps/mobile/src/components/agents/model-picker-content.tsx
  • apps/mobile/src/components/agents/model-picker-content.mounted.test.tsx
  • apps/mobile/src/components/agents/model-selector.tsx
  • apps/mobile/src/components/agents/model-selector.mounted.test.tsx
  • apps/mobile/src/components/agents/picker-search.mounted.test.tsx
  • apps/mobile/src/components/feature-flags-section.tsx
  • apps/mobile/src/components/language-picker-row.tsx
  • apps/mobile/src/components/language-picker-sheet.mounted.test.tsx
  • apps/mobile/src/i18n/catalog-parity.test.ts
  • apps/mobile/src/lib/free-model-data-disclosure.ts
  • apps/mobile/src/lib/free-model-data-disclosure.test.ts
  • tools/i18n/check-catalogs.mjs
  • apps/mobile/src/i18n/locales/*.json (86 non-English catalogs)

Verification Notes

  • Confirmed rtl-text.ts/withRtlInputAlignment and model-id.ts/stripModelPrefix already exist, so the new imports resolve; kilo-auto/free and kilocode/kilo-auto/free both resolve through the new identity check.
  • Confirmed all 86 locale values for preferences.featureFlagApplied/Skipped/NotLoaded retain {{min}}, differ from English, and no catalog still carries the removed English copy; check-catalogs.mjs no longer references the deleted PENDING_TRANSLATION_VALUES symbol.
  • Confirmed the nine locales in the new it.each case have models.auto.free distinct from models.free, so the badge-suppression assertions are satisfiable.
  • No .md files changed; no new subscriptions, timers, or listeners were introduced, so no memory-leak surface was added.

Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

@iscekic
iscekic force-pushed the kwf/explorer-4-visual-defects-on-ios-in-the-single-arabic-sea-8d9f3-5aa7 branch from 944c7bc to de751ff Compare September 23, 2026 11:54
@iscekic
iscekic marked this pull request as ready for review September 23, 2026 12:05
@iscekic
iscekic marked this pull request as draft September 23, 2026 12:26
@iscekic
iscekic force-pushed the kwf/explorer-4-visual-defects-on-ios-in-the-single-arabic-sea-8d9f3-5aa7 branch from 45298e9 to 93dab2d Compare September 23, 2026 16:46
@iscekic
iscekic force-pushed the kwf/explorer-4-visual-defects-on-ios-in-the-single-arabic-sea-8d9f3-5aa7 branch from 516c55c to ca02ee5 Compare September 23, 2026 19:55
@iscekic
iscekic marked this pull request as ready for review September 23, 2026 20:14
@iscekic

iscekic commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator Author

This description names a scenario the proof did not capture:

  • not proved live: language-search-arabic-kb-up.png is no longer on the host that took it, so no publish can carry it

A repeated proof run rebuilds the same evidence, so no proof run is dispatched for a named gap. Merging with this gap open is your decision.

@iscekic
iscekic marked this pull request as draft September 23, 2026 22:18
The branch renamed main's 0258_github_connection_role.sql to
0258_woozy_morbius.sql and dropped 0259_github_connection_role_indexes.sql
with its snapshot, so its journal stopped at idx 258 while main was at 259.
The branch changes no schema and its packages/db/src/schema.ts matches main,
so it authored no migration.

Merge origin/main, take main's migration folder verbatim, and drop the renamed
file. The drizzle CLI reports "No schema changes, nothing to migrate", so no
migration is generated and main's 0258 and 0259 stay in place.

Guards: the packages/db jest suite passes (7 suites, 34 tests), including
migration-journal.test.ts.
main's shared single-line Input already applies withRtlInputAlignment, so
the repository and model picker search fields keep that contract instead of
re-applying the alignment themselves, and the picker search test keeps one
live I18nManager mock.
main's shared Input already brought I18nManager into the model picker
mount test's react-native mock.
@iscekic iscekic added the human-ready The PR is ready for human review. label Sep 25, 2026
@iscekic
iscekic marked this pull request as ready for review September 25, 2026 13:49
@iscekic
iscekic merged commit e72bd74 into main Sep 25, 2026
29 checks passed
@iscekic
iscekic deleted the kwf/explorer-4-visual-defects-on-ios-in-the-single-arabic-sea-8d9f3-5aa7 branch September 25, 2026 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

human-ready The PR is ready for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants