Repository navigation
feat(ui): native-text BibleReader body and footnotes (POC) - #233
Draft
Dustin-Kelley wants to merge 83 commits into
Draft
Dustin-Kelley wants to merge 83 commits into
Dustin-Kelley wants to merge 83 commits into
Conversation
Bump the example dev client to expo@57.0.22 with RN 0.86.3, pin @expo/dom-webview@57.0.1, and move publishable package peers to >=57.0.0 <58.0.0. Add pnpm overrides for transitive Expo deps still inside the supply-chain cooldown window.
Pick up the SDK patch without enabling ios.enableSceneSupport; workspace override and example app pin expo@57.0.23 exactly.
Opt in via expo-build-properties enableSceneSupport and bump the plugin to 57.0.20, which implements the scene delegate wiring required alongside expo@57.0.23 on SDK 57.
Raise peer floors so consumers on React Native 0.86 cannot resolve Reanimated 4.3.x or Worklets 0.8.x, which only declare support through 0.85. Add a major changeset recording the Expo 57 peer requirement.
5970824 raised packages/ui peer floors to >=4.4.0 / >=0.9.1 but did not regenerate pnpm-lock.yaml, causing frozen-lockfile CI to fail. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com>
Consumer-facing docs still listed SDK 56 while published peers require 57.
YPE-5830. Native Card owns header, version control, copyright, and maxWidth. Scripture still paints through BibleTextViewDom.
Disable the version control and skip onVersionPickerPress when chrome metadata has no languageTag, so consumers never receive an empty languageId.
Track which reference/versionId loaded metadata and return null during render when inputs change, so chrome cannot flash stale values before the refetch effect runs.
Apply provider version filters to chrome metadata, restore abbreviation and web background theming, gate the version picker only for consumer handlers, and keep Expo web from showing a dead built-in picker trigger. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com>
Include provider filter lists in the chrome metadata key so a tighten without reference/versionId change drops prohibited chrome immediately, matching the reference-transition safety net. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com>
Match the Web SDK full-bleed contract: the Card surface fills the parent while header, scripture, and footer stay in a centered 600px column. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com>
Include fetchBibleContent in the chrome metadata key so an appKey/apiHost swap drops stale reference/copyright/language before the new lookup resolves. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com>
Co-authored-by: camrun91 <16566029+camrun91@users.noreply.github.com>
…on (#194) * feat(ui)!: compose YouVersionAuthButton on design-system Button YPE-5833 / RNV2-6. The branded control is now Button + Button.Text with the Bible App logo as a child. background still forces the light or dark token scheme. BREAKING CHANGE: YouVersionAuthButton no longer accepts outline, radius, or size. Short, icon, and rectangular variants are gone. The canonical look is a filled, rounded Button with the full localized label. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): keep Trans props off Button.Text in YouVersionAuthButton Wrap the i18n Trans node inside Button.Text instead of using it as Trans parent, so extra Trans props are not forwarded onto the label. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): address YouVersionAuthButton review findings Drop the unlinked example preview route. Collapse sign-in versus sign-out to one decision. Document that core majors only because the packages version together. Cover theme isolation and the bold Trans face. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): pin YouVersionAuthButton fill to scheme background Button default primary is red in dark and hides the Bible App logo. Read tokens via useTokens inside the forced ThemeContext. Cover sign-in error logging and keep outline/radius/size off the public props type. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * docs: match native i18n Trans example to auth button The contributing snippet still taught parent={Text} and a hand-written fontWeight. The auth button nests Trans in Button.Text and bolds with sansFace. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * refactor(ui): read i18n inside YouVersionAuthButton surface AuthButtonSurface already sits under the forced scheme. It can call useSdkTranslation itself instead of taking i18n as a pass-through prop. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): treat empty auth button text as omitted An empty text prop used to fall back to the localized Trans label. Nullish coalescing made it a blank control. Scope the i18n sansFace note to primitives so sheets can keep fontWeight. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): outline YouVersionAuthButton and let the label wrap Bake a scheme border into the locked look (light 1px, dark 2px) without bringing back the outline prop. Override Button.Text to two lines and drop the fixed height so a long locale can wrap. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * refactor(ui): extract AuthButtonLabel from YouVersionAuthButton Keep Trans named Trans. Early-return when the caller passes text. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * chore(changeset): ship YouVersionAuthButton DS work as patch Drop core from the changeset; it has no API change. The fixed group still versions both packages together. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * refactor(ui): bold AuthButtonLabel with design-system Text Trans bold uses DS Text plus sansFace. Pin typography.sm so the brand name stays on the Button.Text size. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): let YouVersionAuthButton label wrap on web Give Button.Text flex: 1 so a narrow parent wraps to two lines instead of ellipsizing on one. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * docs: add PR 194 Expo web QA screenshots for local download Temporary PNGs so Dustin can pull them via the GitHub API onto his Desktop. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * docs: remove temporary PR 194 screenshot drop folder Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): restore YouVersionAuthButton post-DS-9 shape on Button Keep the old padding, logo gap, and no default border while composing the design-system Button. Label color comes from Button context. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): match YouVersionAuthButton chrome to Swift Compose Button outline, hug content, and use Swift padding, gap, and logo size so hosts place the pill. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com>
* feat(ui): add native Bible chapter picker Amp-Thread-ID: https://ampcode.com/threads/T-01a0c4d9-366a-702e-a0d8-e56d50e888bc Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> * fix(ui): refine native chapter picker Amp-Thread-ID: https://ampcode.com/threads/T-01a0c4d9-366a-702e-a0d8-e56d50e888bc Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> * fix(ui): polish chapter picker interactions Amp-Thread-ID: https://ampcode.com/threads/T-01a0c4d9-366a-702e-a0d8-e56d50e888bc Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> * fix(ui): preserve chapter picker sheet theme Amp-Thread-ID: https://ampcode.com/threads/T-01a0c5d4-3d6c-712f-b216-cb65fb75357f Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> * fix(ui): address chapter picker review feedback Keep the selected-book fade on one color, avoid reloading the catalog when provider filters are recreated with the same contents, and scroll the selected chapter back into view after an order change. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): ignore chapter picks for a revoked Bible version Drop the loaded catalog as soon as provider filters change, and refuse a selection when the current filters no longer allow that version. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com>
* feat(ui): hybridize BibleCard chrome with DOM BibleTextView YPE-5830. Native Card owns header, version control, copyright, and maxWidth. Scripture still paints through BibleTextViewDom. * fix: clear BibleCard chrome metadata before refetch * fix: guard BibleCard version picker until language tag loads Disable the version control and skip onVersionPickerPress when chrome metadata has no languageTag, so consumers never receive an empty languageId. * fix: invalidate BibleCard chrome metadata synchronously on transition Track which reference/versionId loaded metadata and return null during render when inputs change, so chrome cannot flash stale values before the refetch effect runs. * chore: upgrade example app and packages to Expo SDK 57 Bump the example dev client to expo@57.0.22 with RN 0.86.3, pin @expo/dom-webview@57.0.1, and move publishable package peers to >=57.0.0 <58.0.0. Add pnpm overrides for transitive Expo deps still inside the supply-chain cooldown window. * chore: bump expo to 57.0.23 for iOS 27 lifecycle backport Pick up the SDK patch without enabling ios.enableSceneSupport; workspace override and example app pin expo@57.0.23 exactly. * fix(example): enable iOS 27 UIScene lifecycle for Xcode 27 builds Opt in via expo-build-properties enableSceneSupport and bump the plugin to 57.0.20, which implements the scene delegate wiring required alongside expo@57.0.23 on SDK 57. * fix(ui): tighten Reanimated/Worklets peers for RN 0.86 Raise peer floors so consumers on React Native 0.86 cannot resolve Reanimated 4.3.x or Worklets 0.8.x, which only declare support through 0.85. Add a major changeset recording the Expo 57 peer requirement. * fix: sync lockfile with Reanimated/Worklets peer floors 5970824 raised packages/ui peer floors to >=4.4.0 / >=0.9.1 but did not regenerate pnpm-lock.yaml, causing frozen-lockfile CI to fail. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> * docs: align READMEs with Expo SDK 57 peer contract Consumer-facing docs still listed SDK 56 while published peers require 57. * fix(ui): address BibleCard hybrid chrome review feedback Apply provider version filters to chrome metadata, restore abbreviation and web background theming, gate the version picker only for consumer handlers, and keep Expo web from showing a dead built-in picker trigger. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> * fix(ui): clear BibleCard chrome when version filters change Include provider filter lists in the chrome metadata key so a tighten without reference/versionId change drops prohibited chrome immediately, matching the reference-transition safety net. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> * fix(ui): keep 600px inner column for BibleCard maxWidth 100% Match the Web SDK full-bleed contract: the Card surface fills the parent while header, scripture, and footer stay in a centered 600px column. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> * fix(ui): clear BibleCard chrome when content client changes Include fetchBibleContent in the chrome metadata key so an appKey/apiHost swap drops stale reference/copyright/language before the new lookup resolves. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> * YPE-5833 / RNV2-6: compose YouVersionAuthButton on design-system Button (#194) * feat(ui)!: compose YouVersionAuthButton on design-system Button YPE-5833 / RNV2-6. The branded control is now Button + Button.Text with the Bible App logo as a child. background still forces the light or dark token scheme. BREAKING CHANGE: YouVersionAuthButton no longer accepts outline, radius, or size. Short, icon, and rectangular variants are gone. The canonical look is a filled, rounded Button with the full localized label. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): keep Trans props off Button.Text in YouVersionAuthButton Wrap the i18n Trans node inside Button.Text instead of using it as Trans parent, so extra Trans props are not forwarded onto the label. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): address YouVersionAuthButton review findings Drop the unlinked example preview route. Collapse sign-in versus sign-out to one decision. Document that core majors only because the packages version together. Cover theme isolation and the bold Trans face. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): pin YouVersionAuthButton fill to scheme background Button default primary is red in dark and hides the Bible App logo. Read tokens via useTokens inside the forced ThemeContext. Cover sign-in error logging and keep outline/radius/size off the public props type. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * docs: match native i18n Trans example to auth button The contributing snippet still taught parent={Text} and a hand-written fontWeight. The auth button nests Trans in Button.Text and bolds with sansFace. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * refactor(ui): read i18n inside YouVersionAuthButton surface AuthButtonSurface already sits under the forced scheme. It can call useSdkTranslation itself instead of taking i18n as a pass-through prop. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): treat empty auth button text as omitted An empty text prop used to fall back to the localized Trans label. Nullish coalescing made it a blank control. Scope the i18n sansFace note to primitives so sheets can keep fontWeight. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): outline YouVersionAuthButton and let the label wrap Bake a scheme border into the locked look (light 1px, dark 2px) without bringing back the outline prop. Override Button.Text to two lines and drop the fixed height so a long locale can wrap. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * refactor(ui): extract AuthButtonLabel from YouVersionAuthButton Keep Trans named Trans. Early-return when the caller passes text. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * chore(changeset): ship YouVersionAuthButton DS work as patch Drop core from the changeset; it has no API change. The fixed group still versions both packages together. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * refactor(ui): bold AuthButtonLabel with design-system Text Trans bold uses DS Text plus sansFace. Pin typography.sm so the brand name stays on the Button.Text size. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): let YouVersionAuthButton label wrap on web Give Button.Text flex: 1 so a narrow parent wraps to two lines instead of ellipsizing on one. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * docs: add PR 194 Expo web QA screenshots for local download Temporary PNGs so Dustin can pull them via the GitHub API onto his Desktop. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * docs: remove temporary PR 194 screenshot drop folder Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): restore YouVersionAuthButton post-DS-9 shape on Button Keep the old padding, logo gap, and no default border while composing the design-system Button. Label color comes from Button context. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): match YouVersionAuthButton chrome to Swift Compose Button outline, hug content, and use Swift padding, gap, and logo size so hosts place the pill. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * chore: sync react native localization (#200) Co-authored-by: camrun91 <16566029+camrun91@users.noreply.github.com> * feat(ui): YPE-5836: Add native Bible chapter picker (#204) * feat(ui): add native Bible chapter picker Amp-Thread-ID: https://ampcode.com/threads/T-01a0c4d9-366a-702e-a0d8-e56d50e888bc Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> * fix(ui): refine native chapter picker Amp-Thread-ID: https://ampcode.com/threads/T-01a0c4d9-366a-702e-a0d8-e56d50e888bc Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> * fix(ui): polish chapter picker interactions Amp-Thread-ID: https://ampcode.com/threads/T-01a0c4d9-366a-702e-a0d8-e56d50e888bc Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> * fix(ui): preserve chapter picker sheet theme Amp-Thread-ID: https://ampcode.com/threads/T-01a0c5d4-3d6c-712f-b216-cb65fb75357f Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> * fix(ui): address chapter picker review feedback Keep the selected-book fade on one color, avoid reloading the catalog when provider filters are recreated with the same contents, and scroll the selected chapter back into view after an order change. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): ignore chapter picks for a revoked Bible version Drop the loaded catalog as soon as provider filters change, and refuse a selection when the current filters no longer allow that version. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * feat(ui): YPE-5834: Add native Bible version picker Replace the Expo DOM picker body with a native sheet so version and language lists stay on device. * fix(ui): satisfy oxlint on the version picker Parse the language tab and device language codes without a type assertion or a typeof check. * fix(ui): hide picker languages with no usable versions Provider version and language filters were applied only on the versions panel, so the language lists could open a language that then showed no versions. Derive the suggested, all, and search lists from versions the active filters still allow. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> * fix(ui): keep the version picker usable after a failed selection A rejected onSelect was swallowed by the sheet, so the picker recorded and highlighted the version the host refused. A current version with no language also hid the catalog. Let the rejection reach the picker, publish the catalog anyway, and reset the sheet by unmounting on close. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> * fix(ui): offer retry when the current version lookup fails A thrown metadata lookup left the versions panel looking empty. Keep the language catalog available, and show Retry on that transient failure so the same lookup can be attempted again. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> * fix(ui): keep recent versions selectable when version lookup fails The retry state replaced the whole versions list. Recent versions are already in the catalog, so show them with Retry and let the user select one while the current-version lookup is still failing. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> * feat(ui): refine native Bible version picker sheet (#217) * feat(ui): refine native Bible version picker design Amp-Thread-ID: https://ampcode.com/threads/T-01a0d979-8f8f-73f8-b9fe-8c5a5a518cae Co-authored-by: Amp <amp@ampcode.com> * fix(ui): address Bible version picker review feedback Amp-Thread-ID: https://ampcode.com/threads/T-01a0d979-8f8f-73f8-b9fe-8c5a5a518cae Co-authored-by: Amp <amp@ampcode.com> * fix strings pulled down. --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Dustin Kelley <141975656+Dustin-Kelley@users.noreply.github.com> Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> Co-authored-by: platform-localization-pr-bot[bot] <294853593+platform-localization-pr-bot[bot]@users.noreply.github.com> Co-authored-by: camrun91 <16566029+camrun91@users.noreply.github.com> Co-authored-by: Dustin Kelley <Kelleydustin2018@gmail.com> Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> Co-authored-by: Amp <amp@ampcode.com>
* feat(ui): hybridize BibleCard chrome with DOM BibleTextView YPE-5830. Native Card owns header, version control, copyright, and maxWidth. Scripture still paints through BibleTextViewDom. * fix: clear BibleCard chrome metadata before refetch * fix: guard BibleCard version picker until language tag loads Disable the version control and skip onVersionPickerPress when chrome metadata has no languageTag, so consumers never receive an empty languageId. * fix: invalidate BibleCard chrome metadata synchronously on transition Track which reference/versionId loaded metadata and return null during render when inputs change, so chrome cannot flash stale values before the refetch effect runs. * chore: upgrade example app and packages to Expo SDK 57 Bump the example dev client to expo@57.0.22 with RN 0.86.3, pin @expo/dom-webview@57.0.1, and move publishable package peers to >=57.0.0 <58.0.0. Add pnpm overrides for transitive Expo deps still inside the supply-chain cooldown window. * chore: bump expo to 57.0.23 for iOS 27 lifecycle backport Pick up the SDK patch without enabling ios.enableSceneSupport; workspace override and example app pin expo@57.0.23 exactly. * fix(example): enable iOS 27 UIScene lifecycle for Xcode 27 builds Opt in via expo-build-properties enableSceneSupport and bump the plugin to 57.0.20, which implements the scene delegate wiring required alongside expo@57.0.23 on SDK 57. * fix(ui): tighten Reanimated/Worklets peers for RN 0.86 Raise peer floors so consumers on React Native 0.86 cannot resolve Reanimated 4.3.x or Worklets 0.8.x, which only declare support through 0.85. Add a major changeset recording the Expo 57 peer requirement. * fix: sync lockfile with Reanimated/Worklets peer floors 5970824 raised packages/ui peer floors to >=4.4.0 / >=0.9.1 but did not regenerate pnpm-lock.yaml, causing frozen-lockfile CI to fail. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> * docs: align READMEs with Expo SDK 57 peer contract Consumer-facing docs still listed SDK 56 while published peers require 57. * fix(ui): address BibleCard hybrid chrome review feedback Apply provider version filters to chrome metadata, restore abbreviation and web background theming, gate the version picker only for consumer handlers, and keep Expo web from showing a dead built-in picker trigger. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> * fix(ui): clear BibleCard chrome when version filters change Include provider filter lists in the chrome metadata key so a tighten without reference/versionId change drops prohibited chrome immediately, matching the reference-transition safety net. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> * fix(ui): keep 600px inner column for BibleCard maxWidth 100% Match the Web SDK full-bleed contract: the Card surface fills the parent while header, scripture, and footer stay in a centered 600px column. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> * fix(ui): clear BibleCard chrome when content client changes Include fetchBibleContent in the chrome metadata key so an appKey/apiHost swap drops stale reference/copyright/language before the new lookup resolves. Co-authored-by: Cameron Llewellyn <cameron.b.llewellyn@gmail.com> * feat(core): wrap platform-core SearchClient (YPE-5746) (#180) * feat(core): add placeholder Search client YPE-5706: temporary Search HTTP in expo-core until platform-core ships SearchClient. Public hook and types only; wrapper stays internal. Co-authored-by: Cursor <cursoragent@cursor.com> * test(core): cover useSearch outside provider YPE-5706: hook must throw when used without YouVersionProvider. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(core): wrap platform-core SearchClient (YPE-5746) Delete the local Search HTTP client and wrap SearchClient from @youversion/platform-core 2.13.0. Thrown errors map to the existing RN Result kinds. Verse hits use id. Query lists are { queries }. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * style(core): drop restated Search comments The USFM tests already pin verse-only three-segment parsing. The exports tests already pin the public surface. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(core): reject unsafe integers in bibleReferenceFromUsfm Digit-only USFM chapter and verse segments can parse past Number.MAX_SAFE_INTEGER. Require a positive safe integer. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(core): reject malformed USFM book identifiers Require a 3-character uppercase alphanumeric book code so punctuation, whitespace, and overlong ids return null. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * feat(ui): BibleReaderNavigation chapter jumps (YPE-5745) (#182) * feat(core): add placeholder Search client YPE-5706: temporary Search HTTP in expo-core until platform-core ships SearchClient. Public hook and types only; wrapper stays internal. Co-authored-by: Cursor <cursoragent@cursor.com> * test(core): cover useSearch outside provider YPE-5706: hook must throw when used without YouVersionProvider. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(core): wrap platform-core SearchClient (YPE-5746) Delete the local Search HTTP client and wrap SearchClient from @youversion/platform-core 2.13.0. Thrown errors map to the existing RN Result kinds. Verse hits use id. Query lists are { queries }. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * style(core): drop restated Search comments The USFM tests already pin verse-only three-segment parsing. The exports tests already pin the public surface. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(core): reject unsafe integers in bibleReferenceFromUsfm Digit-only USFM chapter and verse segments can parse past Number.MAX_SAFE_INTEGER. Require a positive safe integer. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * feat(ui): add BibleReaderNavigation for chapter jumps Public request/focusReference object so a host can jump the Reader before mount. Scroll-to-verse waits. YPE-5745. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): keep chapter jumps across discarded renders Consume the pending BibleReaderNavigation request after commit so a retried render cannot drop the host's chapter jump. Co-authored-by: Cursor <cursoragent@cursor.com> * docs(ui): request the chapter jump once in the host example Call request when creating BibleReaderNavigation so a parent re-render does not queue the same jump again. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): apply reader jumps after the paint commits Keep the first-paint overlay, but wait to set book/chapter/version so a discarded render cannot notify the host of a chapter that never showed. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): hide reader navigation queue controls Keep request and focusReference as the host API. Move subscribe, snapshot, and consume helpers off the exported class so a host cannot clear a jump before the Reader sees it. Drop unused consumePending. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): persist reader jumps as one location Write book, chapter, and version in a single Reader Location patch so an uncontrolled jump cannot save a mixed book with the old chapter. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * docs(ui): note one Reader per navigation object Hosts should pass one BibleReaderNavigation to one mounted Reader. Broadcast across stacked readers is left for a later issue if needed. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * feat(ui): match native Reader chrome to Swift Drop the avatar row. Half-pills, overlay chapter buttons, and a More menu keep the same host presses. Search stays off this PR. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): lift Reader overlay nav above the iOS tab bar Prev and next sat 24pt from the reader bottom, on SampleApp tabs, so those presses hit Bible or Profile instead of changing chapter. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(ui): retarget Reader chrome to Swift PR 268 Previous and next live in the chapter capsule. Overlay circles are gone so the toolbar matches the current Swift header. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): polish v2 Reader toolbar chrome Match Figma capsules, a softer halo, side padding, and More-menu icons so the native row reads like the v2 file. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): finish v2 toolbar leftovers from self-review Cap the version pill so Select version cannot squeeze the chapter row. Drop unused GearIcon and avatar copy. Open More while auth is restoring. Co-authored-by: Cursor <cursoragent@cursor.com> * refactor(ui): delete unused Avatar primitive The v2 toolbar no longer mounts it. Drop the component, its tests, and the internal barrel export. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): even the Reader toolbar gaps around More Size More to the icon so the 8px gap matches the space between the chapter and version chips. Co-authored-by: Cursor <cursoragent@cursor.com> * revert(ui): keep userAvatarAlt in synced locale catalogs Locale JSON is generated from platform-localization. Dropping the unused key here fails Greptile. Leave the string until that repo deletes it. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): match More menu icons to Swift glyphs Use San Francisco textformat.size for Fonts & Settings and person for sign in/out. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(ui): restack Reader Search onto Swift chrome Search belongs in the 5953 spacer. The old row put it between version and gear, and that chrome is gone. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): keep 5745 navigation consume API on Search rebase Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): keep combined Reader Location jumps after Search rebase Co-authored-by: Cursor <cursoragent@cursor.com> * refactor(ui): delete unused components/ui PersonIcon The More menu still uses native/icons/person-icon.tsx. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): stop the Reader example from jumping every render The sample called navigation.request after every ReaderScreen render, so a copied example reset the reader to John 3 on unrelated updates. The request now happens once, inside the same useMemo that creates the navigation object. Drop the hand-written Spanish search strings. Missing keys fall back to English until Crowdin returns them. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * YPE-5833 / RNV2-6: compose YouVersionAuthButton on design-system Button (#194) * feat(ui)!: compose YouVersionAuthButton on design-system Button YPE-5833 / RNV2-6. The branded control is now Button + Button.Text with the Bible App logo as a child. background still forces the light or dark token scheme. BREAKING CHANGE: YouVersionAuthButton no longer accepts outline, radius, or size. Short, icon, and rectangular variants are gone. The canonical look is a filled, rounded Button with the full localized label. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): keep Trans props off Button.Text in YouVersionAuthButton Wrap the i18n Trans node inside Button.Text instead of using it as Trans parent, so extra Trans props are not forwarded onto the label. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): address YouVersionAuthButton review findings Drop the unlinked example preview route. Collapse sign-in versus sign-out to one decision. Document that core majors only because the packages version together. Cover theme isolation and the bold Trans face. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): pin YouVersionAuthButton fill to scheme background Button default primary is red in dark and hides the Bible App logo. Read tokens via useTokens inside the forced ThemeContext. Cover sign-in error logging and keep outline/radius/size off the public props type. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * docs: match native i18n Trans example to auth button The contributing snippet still taught parent={Text} and a hand-written fontWeight. The auth button nests Trans in Button.Text and bolds with sansFace. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * refactor(ui): read i18n inside YouVersionAuthButton surface AuthButtonSurface already sits under the forced scheme. It can call useSdkTranslation itself instead of taking i18n as a pass-through prop. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): treat empty auth button text as omitted An empty text prop used to fall back to the localized Trans label. Nullish coalescing made it a blank control. Scope the i18n sansFace note to primitives so sheets can keep fontWeight. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): outline YouVersionAuthButton and let the label wrap Bake a scheme border into the locked look (light 1px, dark 2px) without bringing back the outline prop. Override Button.Text to two lines and drop the fixed height so a long locale can wrap. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * refactor(ui): extract AuthButtonLabel from YouVersionAuthButton Keep Trans named Trans. Early-return when the caller passes text. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * chore(changeset): ship YouVersionAuthButton DS work as patch Drop core from the changeset; it has no API change. The fixed group still versions both packages together. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * refactor(ui): bold AuthButtonLabel with design-system Text Trans bold uses DS Text plus sansFace. Pin typography.sm so the brand name stays on the Button.Text size. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): let YouVersionAuthButton label wrap on web Give Button.Text flex: 1 so a narrow parent wraps to two lines instead of ellipsizing on one. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * docs: add PR 194 Expo web QA screenshots for local download Temporary PNGs so Dustin can pull them via the GitHub API onto his Desktop. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * docs: remove temporary PR 194 screenshot drop folder Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): restore YouVersionAuthButton post-DS-9 shape on Button Keep the old padding, logo gap, and no default border while composing the design-system Button. Label color comes from Button context. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): match YouVersionAuthButton chrome to Swift Compose Button outline, hug content, and use Swift padding, gap, and logo size so hosts place the pill. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * chore: sync react native localization (#200) Co-authored-by: camrun91 <16566029+camrun91@users.noreply.github.com> * refactor(ui): inline the Reader Search field The design-system Input had one caller, and that caller turned its border off. The sheet now uses TextInput directly. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * feat(ui): v2 toolbar (YPE-5953) (#202) * feat(ui): match native Reader chrome to Swift Drop the avatar row. Half-pills, overlay chapter buttons, and a More menu keep the same host presses. Search stays off this PR. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): lift Reader overlay nav above the iOS tab bar Prev and next sat 24pt from the reader bottom, on SampleApp tabs, so those presses hit Bible or Profile instead of changing chapter. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(ui): retarget Reader chrome to Swift PR 268 Previous and next live in the chapter capsule. Overlay circles are gone so the toolbar matches the current Swift header. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): polish v2 Reader toolbar chrome Match Figma capsules, a softer halo, side padding, and More-menu icons so the native row reads like the v2 file. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): finish v2 toolbar leftovers from self-review Cap the version pill so Select version cannot squeeze the chapter row. Drop unused GearIcon and avatar copy. Open More while auth is restoring. Co-authored-by: Cursor <cursoragent@cursor.com> * refactor(ui): delete unused Avatar primitive The v2 toolbar no longer mounts it. Drop the component, its tests, and the internal barrel export. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): even the Reader toolbar gaps around More Size More to the icon so the 8px gap matches the space between the chapter and version chips. Co-authored-by: Cursor <cursoragent@cursor.com> * revert(ui): keep userAvatarAlt in synced locale catalogs Locale JSON is generated from platform-localization. Dropping the unused key here fails Greptile. Leave the string until that repo deletes it. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): match More menu icons to Swift glyphs Use San Francisco textformat.size for Fonts & Settings and person for sign in/out. Co-authored-by: Cursor <cursoragent@cursor.com> * refactor(ui): delete unused components/ui PersonIcon The More menu still uses native/icons/person-icon.tsx. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): address review feedback on host toolbar presses The release note said hosts keep the same presses. Settings and sign-in now open from More, and the retired avatar test ids are named. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): address review feedback on capsule clipping Light mode keeps the shadow on the outer pill. Labels and press fills clip on an inner view. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): address review feedback on the More hit target The More pressable is 44 points. The icon stays 24, and the test checks that frame. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * feat(ui): polish Reader Search open state Focus the field when the sheet opens, match the search pill to the other toolbar capsules, and show three trending and recent queries. Co-authored-by: Cursor <cursoragent@cursor.com> * refactor(ui): simplify styles in BibleReaderSearchSheet * fix(ui): use synced Reader Search strings The locale check blocks a hand-edited catalog. Call the synced keys, and read the focus spy from its context so typecheck accepts it. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(ui): YPE-5836: Add native Bible chapter picker (#204) * feat(ui): add native Bible chapter picker Amp-Thread-ID: https://ampcode.com/threads/T-01a0c4d9-366a-702e-a0d8-e56d50e888bc Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> * fix(ui): refine native chapter picker Amp-Thread-ID: https://ampcode.com/threads/T-01a0c4d9-366a-702e-a0d8-e56d50e888bc Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> * fix(ui): polish chapter picker interactions Amp-Thread-ID: https://ampcode.com/threads/T-01a0c4d9-366a-702e-a0d8-e56d50e888bc Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> * fix(ui): preserve chapter picker sheet theme Amp-Thread-ID: https://ampcode.com/threads/T-01a0c5d4-3d6c-712f-b216-cb65fb75357f Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> * fix(ui): address chapter picker review feedback Keep the selected-book fade on one color, avoid reloading the catalog when provider filters are recreated with the same contents, and scroll the selected chapter back into view after an order change. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): ignore chapter picks for a revoked Bible version Drop the loaded catalog as soon as provider filters change, and refuse a selection when the current filters no longer allow that version. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): drop the Reader Search capsule Search is a plain 24pt icon with 8pt of padding. The toolbar row uses 16pt on the leading edge and no trailing pad. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): inset the Reader More control from the trailing edge The row had no trailing pad, so More sat on the screen edge. Add 8pt on that side. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): keep a trailing space after a submitted search Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): retry a search page when its hits cannot be titled A later page with hits and no titles stays retryable instead of marking those verses seen. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): label search retry buttons Retry The failed search and the page-error control were saying Error. Co-authored-by: Cursor <cursoragent@cursor.com> * test(ui): press a bad search result on the real sheet The reader mock never called the sheet, so a bad id could still navigate and the test would pass. Co-authored-by: Cursor <cursoragent@cursor.com> * docs(ui): say Cancel in the Reader Search changeset The header already uses the Cancel string. The release note was still saying Done. Co-authored-by: Cursor <cursoragent@cursor.com> * chore(ui): delete the unused font settings icon The More menu still uses AaIcon, and nothing imported this file. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): narrow the search view before retrying in the test Typecheck rejected footer on the full search view after the await. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(ui): focus a verse across the Expo DOM bridge A Search tap should scroll to the verse. The WebView can only take a plain object, so the DOM wrapper builds BibleReaderNavigation and calls focusReference when seq changes. * fix(ui): drop the example John 3:16 focus control The example Reader is not a focus demo. Search still focuses through the Reader's own navigation. * fix(ui): keep a repeated or rejected verse focus from moving the reader A WebView reload was jumping back to the last focused verse, and a passage the Web SDK rejects was clearing the page. * fix(ui): type the verse focus mocks with jest's two type arguments tsc rejects a single type argument on jest.fn, which failed the PR typecheck. * fix(ui): apply a verse focus queued before the Reader mounts The WebView treated the first focus number as already handled, so a focus waiting at startup never scrolled. A later reload still skips that same number. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): show the suggestion spinner only after the request starts The debounce wait stays blank. The spinner keeps the list height so the sheet does not collapse. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): skip a repeat search for the same query and version Pressing Search again after results land was clearing the list and fetching it again. A failed search still retries. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): announce a failed search next to Retry A failed search and a failed next page only showed Retry. Screen readers now hear Error when that state appears. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): load the next search page at the last five rows The list waited until the last fifth of the viewport. It now requests the next page once a row in the last five is on screen. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): finish remaining Search review notes Give the field a search role, grow Search and Clear to 44pt hits, and document that Search taps and focusReference scroll and dim. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): address Search review follow-ups Prevent verse focus from replaying after a WebView reload, skip a whitespace-only repeat search, and give Retry a 44pt hit target. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): match Search clear to the picker field Use the same 18pt ClearIcon, trailing placement, and 10pt hit slop as the native picker search field. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): apply verse focus only after the WebView reports it A focus requested while the WebView is loading was marked applied on the native side and then skipped when the WebView became ready. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): show completed search results again after a whitespace edit Pressing Search on the same query restores the page already loaded and keeps the typed space. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): give Search Clear a 44pt touch target The 18pt icon stays. The button itself is 44pt so the extra area does not cover the text field. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): drop a void call the linter rejects The focus report already returns nothing, so the void operator is not allowed. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): let Search delete whitespace after restoring results setQuery ignored any edit equal to the submitted query. A restored page keeps the typed text ("hope "), so backspacing to "hope" was dropped and the field snapped back. Compare against the displayed field text instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(ui): keep the last of two quick Search edits Compare each edit against the reducer's current state instead of the last render, so a type-then-delete before a re-render is not dropped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(ui): keep paging Search past a page of repeated verses A next page whose hits were all already shown added no rows, so the list never scrolled to ask again and results stopped early. Follow the new cursor instead; stop if the API hands back the same one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(ui): stop Search paging when cursors cycle Following the cursor past repeat-only pages looped forever if the API cycled cursors (A -> B -> A). Remember every fetched cursor for the result set and stop when a repeat-only page points back at one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(ui): dedupe the first page of Search results Later pages already dropped repeated hits, but page one used the raw list, so a repeated id rendered two rows with one key and fetched the passage twice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(ui): keep Search focus and theme with the Reader The navigation object stores the applied focus sequence, so remounting the Reader does not send an acknowledged verse to the Web SDK again. Search content uses the Reader theme, so result text matches the sheet when the provider scheme differs. * fix(ui): scope verse focus to the navigation object A replacement navigation object restarts its focus sequence at 1. The WebView now tracks which object that sequence belongs to, so the new object's first focus still runs once. Co-authored-by: Cursor <cursoragent@cursor.com> * test(ui): show a late verse-focus ack marks the replacement reader The callback still accepts only the sequence. After a navigation swap, that sequence is stored on the reader now on screen. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): ignore a verse-focus ack from another navigation stream Expo delivers the action to the reader on screen. The acknowledgment names its stream, so a late reply from the previous navigation object does not mark the replacement. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Dustin Kelley <141975656+Dustin-Kelley@users.noreply.github.com> Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> Co-authored-by: Dustin Kelley <Kelleydustin2018@gmail.com> Co-authored-by: platform-localization-pr-bot[bot] <294853593+platform-localization-pr-bot[bot]@users.noreply.github.com> Co-authored-by: camrun91 <16566029+camrun91@users.noreply.github.com> Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Make local iOS simulator development reliable (#197) * chore: make iOS simulator development reliable Amp-Thread-ID: https://ampcode.com/threads/T-01a0b05a-be6e-7792-8c35-a659fd7f4b18 Co-authored-by: Amp <amp@ampcode.com> * fix: harden iOS launcher lifecycle Amp-Thread-ID: https://ampcode.com/threads/T-01a0b05a-be6e-7792-8c35-a659fd7f4b18 Co-authored-by: Amp <amp@ampcode.com> * fix: stop iOS launcher process trees Amp-Thread-ID: https://ampcode.com/threads/T-01a0b05a-be6e-7792-8c35-a659fd7f4b18 Co-authored-by: Amp <amp@ampcode.com> * fix: improve iOS doctor diagnostics Amp-Thread-ID: https://ampcode.com/threads/T-01a0b05a-be6e-7792-8c35-a659fd7f4b18 Co-authored-by: Amp <amp@ampcode.com> * fix: align iOS Metro and simulator selection Amp-Thread-ID: https://ampcode.com/threads/T-01a0d8ed-5471-76a9-aa27-37954ee1b920 Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> --------- Co-authored-by: Amp <amp@ampcode.com> * chore: sync react native localization --------- Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com> Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: camrun91 <16566029+camrun91@users.noreply.github.com>
The hybrid card accepts the Web prop and drops it, so a caller cannot set direction.
The public prop reached BibleCardBody and stopped there, so scripture and footnotes stayed in the default direction.
* feat(ui): native BibleReader settings content Render font size, line spacing, and font family controls in the native settings sheet, and remove the unused DOM settings and version picker content impls. Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com> * fix(ui): match native reader settings to the webview sheet Let the controls grow with their labels, show the readable font names, and keep dark mode on the sheet surface instead of a white selected chip. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(ui): open the search sheet to the full viewport The results area was half the screen, so the sheet stopped there. Size it to the viewport so it opens all the way up. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): satisfy typecheck in the sheet tests ReactNode was imported from react-native, and text styles were read as view styles. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): take the synced reader settings strings Drop the hand-edited English keys so this branch uses the catalog already on v2.0. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): keep search results above the keyboard The full-height search sheet cannot rise, so the list pads by the keyboard overlap and the last row can scroll into view. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): wait to show the serif choice until the face is registered The settings preview was drawing Untitled Serif before that face had loaded. Co-authored-by: Cursor <cursoragent@cursor.com> * docs(ui): note the font-size letter is a size sample The letter matches the web settings buttons. The spoken name is already the accessibility label. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): satisfy lint on font readiness and keyboard tests The font hook names its return. The keyboard test uses a keyboard event, and the subscription stub states why the extra fields are unused. Co-authored-by: Cursor <cursoragent@cursor.com> * docs: mark the retired DOM picker notes The version picker is native, and reader settings no longer cross the font bridge. The old notes stay as history. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Dustin Kelley <Dustin-Kelley@users.noreply.github.com>
Settings previously hid the serif option until the Fonts API finished, so users on Inter could not switch back during a slow request despite the bundled fallback.
The theme directory scan rejects any source containing the substring rem; rephrase the useBrandFonts doc comment so CI passes.
Eager Source Serif 4 registration under Untitled Serif names blocked the Fonts API faces from replacing them in Expo Font; settings still show the serif choice while the request is pending.
Register Source Serif 4 immediately for native chrome during slow API calls, then unload and reload faces when remote TTFs arrive so Expo Font can apply Untitled Serif.
tokens.test.ts scans theme files for rem; rename API TTF helpers and wording so CI passes without changing font behavior.
When appKey or apiHost changes, cancelled effect scopes skip registry updates so an older Fonts API response cannot overwrite Untitled Serif faces.
The example's Native tab was the first POC; the shipped reader in packages/ui superseded it. Drops its tab, files, and the platform-core and linkedom deps only it used. Without the example's copy, hoisting nests linkedom's ESM deps beneath it, so Jest now lets linkedom through to transform them. Also clears three lint errors in passage.tsx. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Swift shows the book and chapter only in the toolbar, so the native reader no longer repeats them above the text. Top padding drops from 48 to 16 to match Swift's vertical padding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Swift fills only a line's typographic bounds, so highlighted lines show a gap. iOS line metrics span the whole line box, so the backdrop clips each line to an em band measured off Swift's serif (0.98 up, 0.26 down). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ndroid Android reads colour 0 as unset, so transparent ghost text fell back to black; ghosts now use alpha 0 white. Band and underline windows that spill past their line read from their own line instead of the next one. A full-line inline box grows the line's ascent on Android and takes it from the descent, which clipped a last line's descenders and made lines with verse numbers taller. The box is capped at the band's ascent, with a fill that keeps highlights continuous under labels and footnote icons. The footnote icon rises less on Android to clear the line above. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Selecting a verse remounts its paragraph (the Fabric iOS attachment workaround), which reset the measured lines and size, so the highlight vanished for a frame and returned against a zero-width backdrop. Each block now keeps its last layout per look and starts a remount from it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ASV Psalm 119 opens each stanza with a centred Hebrew letter line (qc), so the first-letter rule laid the whole chapter out right-to-left. The passage's scripture letters now vote; headings still abstain. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Synthesized small caps were 0.75x and untracked; Swift's are about 0.86x cap height and 23% wider. Runs now render at 0.85x with 0.055em tracking. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Per the style spec, matching Kotlin's 32dp (Swift uses 30), so lines wrap at the same words as the other native readers. Top spacing that borrowed GUTTER now uses TOP_PADDING and stays at 16. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Any non-200 read as "unavailable in this version", so a 429 or 5xx told readers the chapter was missing. Only 403 and 404 do now; other failures show the generic request error with Retry, and Retry hides when the passage is unavailable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Xcode 27 replaced Simulator.app with DeviceHub, so `open -a Simulator` failed and stopped dev:ios. Opening the window is now best-effort; the launcher boots the device either way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Tag block layouts with their passage and cancel a pending focus landing on chapter or version change, so it never scrolls or dims the new text. - Footnote sheet follows RTL scripture direction and uses the system serif stand-in until the brand serif registers (SERIF_STANDIN moves to fonts). - A passage parse throw reads as 'failed', not 'offline'. - Changeset: drop the core bump; note the unstable renderer switch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…erse Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Derive highlight paint from the passage on screen, so the outgoing chapter never wears the incoming chapter's colors while it loads. - serifReady reflects whether a serif actually registered; a failed load keeps the stand-in. - Footnote HTML decodes typographic named entities (quotes, dashes, ellipsis). - Cap a focus passage range at 250 verses. - Label and link faces go through sansFace. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The WebView reader stays only for comparison and will be removed. BibleTextView, BibleCard, and VerseOfTheDay still use the WebView. Co-authored-by: Cursor <cursoragent@cursor.com>
Footnotes already render as native text. The old webview file, the sheet loader nothing called, and the DOM sizing helper go with it. Co-authored-by: Cursor <cursoragent@cursor.com>
The native chapter body had no tests, so a broken selection, a cancelled focus, or a missing chapter could ship unnoticed. Co-authored-by: Cursor <cursoragent@cursor.com>
An fp span was glued to the sentence before it. The reader test also sets includeAuth so those props typecheck. Co-authored-by: Cursor <cursoragent@cursor.com>
Lint rejects a typeof check in the native reader test. Co-authored-by: Cursor <cursoragent@cursor.com>
A highlighted paragraph was laying out three copies of itself on every line. Paint it once, cover the rest, and clip that paint so it does not streak into the gutter. Co-authored-by: Cursor <cursoragent@cursor.com>
A full line already sat on the column edge, so the highlight stopped with the letters, and Android left a one-pixel streak under the last line. Give the column a little extra width, pad the words back, and cover that stray pixel. Co-authored-by: Cursor <cursoragent@cursor.com>
The extra 3 points ran the paint into the next verse number, and the footnote bubble crossed the top of the highlight. 0.1em fits in the trailing space, and the bubble sits inside the paint. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
useSerifFace now owns the stand-in swap, so a serif consumer cannot name the brand face before it registers. The footnote sheet also moves its props type below the imports and parses its HTML once per change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A proof of concept that the
BibleReaderscripture body and footnote sheets can render with React Native<Text>instead of Expo DOM WebViews, at visual parity with the Swift and Kotlin SDKs. No native modules.https://www.loom.com/share/5ad15c233898465ca30c2968902905da
Native reader (POC, opt-in)
BibleReaderNativetakes the same props as the DOM reader body and swaps in through the impl registry.unstable_setReaderRenderer('dom' | 'native')picks one; DOM stays the default.transformBibleHtmlunder linkedom, flattened into blocks of verse-tagged runs (packages/ui/src/native/scripture/).lowercaseSmallCaps()and are within 1px of its height.onTextLayoutline metrics. RN has no underline offset, and iOS breaks text underlines at descenders.Native footnote content (YPE-5832, changeset included)
FootnoteContentrenders with native text in both reader modes. It keeps italic notes, bold locators and verse superscripts, sized to match the web sheet.Tooling
pnpm dev:iosfalls back to DeviceHub when Xcode has no Simulator.app (Xcode 27).Cleanup
Not yet covered
q2) wrap later than Swift, which breaks them before the line is full. This predates this branch's fixes and is untraced.Test plan
pnpm lint, the UI packagetsc, and UI Jest (952 passed)🤖 Generated with Claude Code