Skip to content

feat(tui): translation picker with persistent indicator and fuzzy filter#16

Open
ivanmaierg wants to merge 10 commits into
mainfrom
worktree-translation-picker
Open

feat(tui): translation picker with persistent indicator and fuzzy filter#16
ivanmaierg wants to merge 10 commits into
mainfrom
worktree-translation-picker

Conversation

@ivanmaierg

Copy link
Copy Markdown
Owner

Summary

Adds the ability to change Bible translation from inside the TUI. Press t in the reader to open an overlay listing translations from the helloao API, filter by typing, pick with Enter, and the passage re-fetches under the new translation. The active translation name renders in the reader header at all times so you always know what you're reading.

  • New Translation domain type + branded TranslationId flow end-to-end
  • getTranslations added to the BibleRepository port; helloao adapter implements it with a session-scoped closure cache (one fetch per run)
  • getChapter / getPassage use cases promoted: translationId is now an explicit parameter (CLI passes DEFAULT_TRANSLATION_ID; TUI passes from ReaderState)
  • ReaderState variants loading/loaded/network-error carry translationId + translationName; loaded gains a translationPicker sub-state machine (loading | ready | error)
  • 8 new reducer actions cover open, fetch success/failure, query typing, navigation, accept, dismiss
  • Substring filter over name + languageEnglishName, lowercase; cap 50 visible items (no virtualization in OpenTUI)
  • Overlay component matches the chapter-picker UX precedent (accent color, dim chrome, single accent rule)

Scope

In v1: picker overlay, t shortcut, persistent header indicator, substring fuzzy filter, session cache, full passage re-fetch on switch.

Deferred (separate slices): favorites section, cross-run persistence, RTL text rendering, fzf-grade ranked scoring.

SDD artifacts

  • openspec/changes/translation-picker/proposal.md
  • openspec/changes/translation-picker/spec.md — 49 REQs
  • openspec/changes/translation-picker/design.md — state machine, ADRs, key-routing diagram
  • openspec/changes/translation-picker/tasks.md — 47 work-unit tasks, Red/Green TDD pairs
  • openspec/changes/translation-picker/verify-report.md — pass with 4 WARNINGs, 0 CRITICAL

Size note

~2,170 lines changed (production + tests + openspec docs). `tasks.md` flagged this as a high review-budget risk and recommended a chained PR along the getChapter signature-break seam. Shipping as a single PR (`size:exception`) since the signature break and its UI consumer must land together for the feature to deliver any value, and this is a solo repo where round-trip cost > review surface cost. The breaking-change seam is isolated to commit `2a218f0` and is reviewable on its own.

Verify report — known deviations

  • W-01: Filter field is languageEnglishName (display name) not language (ISO code). Functional improvement; spec text drifted from intent — code is correct, spec needs to follow.
  • W-02: Gate order in driver is translation-picker → verse-picker. Spec text reversed them; code is correct per the modal contract.
  • W-03, W-04: Test quality debt on the useTranslationsFetch hook test and three type-only assertions in reader-screen.test.ts. Non-blocking.

Test plan

  • `bun test` — 285 / 285 passing
  • `bunx tsc --noEmit` — clean
  • Manual: launch `bun run dev`, navigate to John 3, press `t`, type "king james", `Enter` → passage re-fetches, header reads "King James Version"
  • Manual: press `t`, `Esc` → overlay dismissed, no state change
  • Manual: open picker with network down → error state renders, `Esc` dismisses
  • Manual: open picker twice in one session → second open is instant (session cache)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant