WIP: chore: park YouVersion brand-font implementation#272
WIP: chore: park YouVersion brand-font implementation#272jaredhightower-youversion wants to merge 4 commits into
Conversation
Adds useOrganizations(organizationIds), which resolves many organizations at once, deduplicated by id, so a list of versions sharing publishers only fetches each organization once. Renames useOrganizationClient -> useOrganizationsClient and exports the new hook.
… Figma Default design tokens now use the brand fonts (--yv-font-sans: Aktiv Grotesk App, --yv-font-serif: Untitled Serif) with Inter / Source Serif 4 as fallbacks, applied SDK-wide. BibleVersionPicker labels, headings, version titles, and publisher names render in Aktiv Grotesk App; the abbreviation tile renders in Untitled Serif Bold. Publisher names are resolved once at the list level via useOrganizations, avoiding N+1 requests when many versions share a publisher.
🦋 Changeset detectedLatest commit: 31b8476 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
| --- | ||
| "@youversion/platform-core": minor | ||
| "@youversion/platform-react-hooks": minor | ||
| "@youversion/platform-react-ui": minor | ||
| --- | ||
|
|
||
| Update the Bible Version picker to match the latest Reader SDK Figma design, adding publisher names and refreshing the abbreviation tile. | ||
|
|
||
| - `@youversion/platform-core`: New `OrganizationsClient` with `getOrganization(organizationId)` for fetching an organization by its UUID (`GET /v1/organizations/{id}`), validated against the existing `OrganizationSchema`. The default design tokens now use the YouVersion brand fonts — `--yv-font-sans` is `'Aktiv Grotesk App'` and `--yv-font-serif` is `'Untitled Serif'`, with Inter / Source Serif 4 retained as graceful fallbacks. This applies SDK-wide (all components, including the Bible reader's serif text). | ||
| - `@youversion/platform-react-hooks`: New `useOrganization(organizationId)` hook (plus `useOrganizationsClient`) following the standard `useApiData` pattern. Fetching is skipped when the id is empty. Also adds `useOrganizations(organizationIds)`, which resolves many organizations at once, deduplicated by id, so a list of versions sharing publishers only fetches each organization once. | ||
| - `@youversion/platform-react-ui`: The `BibleVersionPicker` now uses the YouVersion brand fonts to match Figma — labels, headings, version titles, and the publisher name render in Aktiv Grotesk App (`--font-aktiv`), and the abbreviation tile renders in Untitled Serif Bold (new `--font-untitled-serif` token, CDN `@font-face`, falling back to Source Serif 4). `BibleVersionPicker` now renders the publisher name above the version title for versions that have an `organization_id` (rows without an associated organization render the title only), and recently used versions persist `organization_id` so they display the publisher too. Publisher names are resolved once at the list level via `useOrganizations` instead of per row, avoiding N+1 requests when many versions share a publisher. The `VersionAbbreviationIcon` tile now renders as a 64px square with a 6px radius, warm-neutral (`secondary`) fill, themed border, and serif typography using the foreground text color; recent-version and all-version rows share the same tile styling, and long or trailing-digit abbreviations (e.g. `NASB1995` → `NASB` / `1995`) stay readable without overflowing. |
There was a problem hiding this comment.
Changeset documents unlicensed fonts as a shipped feature
The changeset describes brand fonts (--yv-font-sans: 'Aktiv Grotesk App', --yv-font-serif: 'Untitled Serif') as part of the release. Since the PR is explicitly blocked pending licensing, this entry will need to be rewritten before the branch can be merged — otherwise npm consumers will see documentation for fonts they legally cannot use via SDK distribution. The changeset should either be split (font-only vs. non-font work) or have the brand-font references stripped out.
Prompt To Fix With AI
This is a comment left during a code review.
Path: .changeset/bible-version-picker-figma-updates.md
Line: 1-11
Comment:
**Changeset documents unlicensed fonts as a shipped feature**
The changeset describes brand fonts (`--yv-font-sans: 'Aktiv Grotesk App'`, `--yv-font-serif: 'Untitled Serif'`) as part of the release. Since the PR is explicitly blocked pending licensing, this entry will need to be rewritten before the branch can be merged — otherwise npm consumers will see documentation for fonts they legally cannot use via SDK distribution. The changeset should either be split (font-only vs. non-font work) or have the brand-font references stripped out.
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Summary
31b8476after the fonts were reverted on the main figma PR pending licensing.GET /v1/fonts/{font_id}/stylesheetendpoint (font_id1, sluguntitled-serif) instead of hardcoded CDN@font-face.mainafter that merges so only the font diff remains.PR Description
What changed
Brand fonts (the parked work):
packages/core/src/styles/theme.css—--yv-font-sans: 'Aktiv Grotesk App', 'Inter',--yv-font-serif: 'Untitled Serif', 'Source Serif 4'.packages/ui/src/styles/global.css— CDN@font-facefor Aktiv Grotesk App (400/700) + Untitled Serif (400/700);@theme inline--font-sans/--font-serifbrand defaults +--font-aktiv/--font-untitled-serifaliases.packages/ui/src/lib/verse-html-utils.ts—AKTIV_FONT/UNTITLED_SERIF_FONTconstants +FontFamilyunion.packages/ui/src/components/bible-reader.tsx— Reader font picker brand options; defaultUNTITLED_SERIF_FONT.packages/ui/src/components/bible-version-picker.tsx— abbreviation tile renders Untitled Serif Bold.aktivFontName/untitledSerifFontName(en/es/fr); stories + tests updated.Also present (lands via the figma PR, not unique to this branch):
OrganizationsClient+useOrganization/useOrganizationshooks; publisher names inBibleVersionPicker;VersionAbbreviationIconFigma redesign.Why
Licensing blocker
docs/adr/0001-revert-brand-fonts-pending-licensing.md(onmainvia the figma PR).Greptile Summary
This PR parks two related workstreams together \u2014 brand font adoption (Aktiv Grotesk App + Untitled Serif, blocked on licensing) and a
BibleVersionPickerredesign (publisher names, refreshed abbreviation tile, newOrganizationsClient/useOrganization/useOrganizationshooks). It is explicitly marked Do not merge and is intended as a snapshot for re-application once legal clears.--yv-font-sansand--yv-font-serifdesign tokens updated intheme.css; CDN@font-faceblocks added inglobal.css;AKTIV_FONT/UNTITLED_SERIF_FONTconstants exported fromverse-html-utils.ts; reader and picker components updated to use them as defaults.OrganizationsClientin core,useOrganization/useOrganizations/useOrganizationsClienthooks, andBibleVersionPickerupdated to resolve and display publisher names at the list level (avoiding N+1 requests);organization_idis now persisted inRecentVersionso recent rows can also show publisher names.useOrganizationscache gap: When every ID in a batch fails, theresolved.size === 0guard causes an early return without adding those IDs tocacheRef; they are re-requested on every subsequentidsKeyorclientchange. The hook also exposes noloadingorerrorstate, unlikeuseOrganization.Confidence Score: 3/5
Not safe to merge — the PR is intentionally blocked on licensing, and the useOrganizations cache has a retry bug that should be fixed before the branch lands.
The
useOrganizationshook never records which IDs it has already attempted but failed to fetch. Any totally-failed batch leaves those IDs absent fromcacheRef, so they are re-requested on every change to the ID set or client identity. In a version list where many org IDs return 404, this translates to repeated unnecessary network calls every time the user types in the search box. The changeset also documents unlicensed brand fonts as a released feature, which must be cleaned up before merge.packages/hooks/src/useOrganizations.ts needs the failed-ID tracking fix; .changeset/bible-version-picker-figma-updates.md needs to be rewritten or split to remove brand-font references before merge.
Important Files Changed
Sequence Diagram
%%{init: {'theme': 'neutral'}}%% sequenceDiagram participant BVP as BibleVersionPicker participant UO as useOrganizations participant Cache as cacheRef (Map) participant OC as OrganizationsClient participant API as GET /v1/organizations/:id BVP->>UO: useOrganizations([org_a, org_b, org_a]) UO->>UO: toUniqueIds to [org_a, org_b] UO->>Cache: filter missing (not in cache) Cache-->>UO: "missing = [org_a, org_b]" UO->>OC: Promise.allSettled([getOrg(org_a), getOrg(org_b)]) OC->>API: GET /v1/organizations/org_a OC->>API: GET /v1/organizations/org_b API-->>OC: 200 org_a API-->>OC: 200 org_b OC-->>UO: resolved Map org_a, org_b UO->>Cache: set org_a, set org_b UO->>BVP: organizations Map with org_a and org_b Note over UO,Cache: If ALL fetches fail, resolved.size===0,<br/>early return, IDs NOT cached, re-fetched<br/>on next idsKey or client change%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% sequenceDiagram participant BVP as BibleVersionPicker participant UO as useOrganizations participant Cache as cacheRef (Map) participant OC as OrganizationsClient participant API as GET /v1/organizations/:id BVP->>UO: useOrganizations([org_a, org_b, org_a]) UO->>UO: toUniqueIds to [org_a, org_b] UO->>Cache: filter missing (not in cache) Cache-->>UO: "missing = [org_a, org_b]" UO->>OC: Promise.allSettled([getOrg(org_a), getOrg(org_b)]) OC->>API: GET /v1/organizations/org_a OC->>API: GET /v1/organizations/org_b API-->>OC: 200 org_a API-->>OC: 200 org_b OC-->>UO: resolved Map org_a, org_b UO->>Cache: set org_a, set org_b UO->>BVP: organizations Map with org_a and org_b Note over UO,Cache: If ALL fetches fail, resolved.size===0,<br/>early return, IDs NOT cached, re-fetched<br/>on next idsKey or client changeComments Outside Diff (2)
packages/hooks/src/useOrganizations.ts, line 573-577 (link)When every ID in a
missingbatch fails (network error or 404),resolved.size === 0and the function returns early without updatingcacheRef.current. Those IDs are absent from the cache, so the next timeidsKeyorclientchanges (e.g., the user types in the search box and a new org ID appears in the list), all previously-attempted-but-failed IDs are included inmissingagain and re-requested.The fix is to track attempted IDs separately (e.g., an
attemptedRefSet) and skip them in futuremissingcomputations, regardless of whether they resolved or rejected.Prompt To Fix With AI
packages/hooks/src/useOrganizations.ts, line 548-584 (link)loadingorerrorstate exposed — inconsistent withuseOrganizationuseOrganizationsreturns only{ organizations }, while its siblinguseOrganizationreturns{ organization, loading, error, refetch }. Callers have no way to distinguish "still fetching" from "all fetches failed" — both cases yield an emptyMap. This means theBibleVersionPickersilently renders without publisher names when the network is down, with no observable difference from the pre-fetch state.Prompt To Fix With AI
Prompt To Fix All With AI
Reviews (1): Last reviewed commit: "feat(ui): apply YouVersion brand fonts t..." | Re-trigger Greptile