feat(client): add pull-to-refresh to every content page #314

Merged
james merged 1 commit from 309-pull-to-refresh into main 2026-06-27 01:45:35 +00:00
Owner

Adds a shared pull-to-refresh gesture to every server-data page of the universal client, wired to refetch that page's TanStack Query data.

How

New hook lib/nav/useRefreshControl.tsx takes one or more query results and returns a themed <RefreshControl> (accent-colored spinner via useTheme().tokens.accent, i18n accessibilityLabel, web-safe — the control renders but the gesture is native-only). Each page passes it to its scroll container's refreshControl prop.

Page Container Query hook(s) refetched
notes KeyboardAwareScrollView useNotes
skills KeyboardAwareScrollView useSkillSections
projects KeyboardAwareScrollView useProjects
profile KeyboardAwareScrollView useProfile
experience KeyboardAwareScrollView useEducations, useJobs, useContracts
network KeyboardAwareScrollView usePeople, useOrganizations
network/[id] KeyboardAwareScrollView usePerson, usePeople, useOrganizations
network/orgs/[id] KeyboardAwareScrollView useOrganization, usePeople
account KeyboardAwareScrollView useMe, useAccountIdentities, useAccountTokens, useServerVersion

applications and chat are Placeholder screens (epics #2/#47) with no scroll container or server query — skipped.

Notes

  • Pages whose data spans tabs/cards (experience, network, account) lift the relevant list hooks to the scroll-owning parent so one pull refreshes them all via the shared TanStack cache. Minor behavior change: those lists now fetch on page mount rather than lazily per tab — extra requests are small and keep data fresher.
  • Added common.refresh to en.json (sentence case) for the control's accessibility label.

Verification

  • pnpm -F @carol/client typecheck — clean
  • pnpm -F @carol/client lint — clean
  • pnpm -F @carol/client test — 131 pass

Closes #309

🤖 Generated with Claude Code

Adds a shared pull-to-refresh gesture to every server-data page of the universal client, wired to refetch that page's TanStack Query data. ## How New hook `lib/nav/useRefreshControl.tsx` takes one or more query results and returns a themed `<RefreshControl>` (accent-colored spinner via `useTheme().tokens.accent`, i18n `accessibilityLabel`, web-safe — the control renders but the gesture is native-only). Each page passes it to its scroll container's `refreshControl` prop. | Page | Container | Query hook(s) refetched | |---|---|---| | notes | KeyboardAwareScrollView | `useNotes` | | skills | KeyboardAwareScrollView | `useSkillSections` | | projects | KeyboardAwareScrollView | `useProjects` | | profile | KeyboardAwareScrollView | `useProfile` | | experience | KeyboardAwareScrollView | `useEducations`, `useJobs`, `useContracts` | | network | KeyboardAwareScrollView | `usePeople`, `useOrganizations` | | network/[id] | KeyboardAwareScrollView | `usePerson`, `usePeople`, `useOrganizations` | | network/orgs/[id] | KeyboardAwareScrollView | `useOrganization`, `usePeople` | | account | KeyboardAwareScrollView | `useMe`, `useAccountIdentities`, `useAccountTokens`, `useServerVersion` | `applications` and `chat` are Placeholder screens (epics #2/#47) with no scroll container or server query — skipped. ## Notes - Pages whose data spans tabs/cards (experience, network, account) lift the relevant list hooks to the scroll-owning parent so one pull refreshes them all via the shared TanStack cache. Minor behavior change: those lists now fetch on page mount rather than lazily per tab — extra requests are small and keep data fresher. - Added `common.refresh` to `en.json` (sentence case) for the control's accessibility label. ## Verification - `pnpm -F @carol/client typecheck` — clean - `pnpm -F @carol/client lint` — clean - `pnpm -F @carol/client test` — 131 pass Closes #309 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(client): add pull-to-refresh to every content page
All checks were successful
Commits / Conventional Commits (pull_request) Successful in 13s
PR / Static analysis (pull_request) Successful in 46s
PR / OSV-Scanner (pull_request) Successful in 34s
PR / Trivy (image) (pull_request) Successful in 1m52s
PR / pnpm audit (pull_request) Successful in 3m3s
PR / Typecheck (pull_request) Successful in 3m8s
PR / Package age policy (soft) (pull_request) Successful in 25s
PR / OpenAPI (pull_request) Successful in 3m17s
PR / Lint (pull_request) Successful in 3m35s
Secrets / gitleaks (pull_request) Successful in 38s
PR / Client (web export smoke) (pull_request) Successful in 4m9s
PR / Build (pull_request) Successful in 4m32s
PR / Test (sqlite) (pull_request) Successful in 4m46s
PR / Test (postgres) (pull_request) Successful in 4m55s
PR / Coverage (soft) (pull_request) Successful in 4m8s
a1d2bdb520
Add a shared pull-to-refresh gesture to every server-data page of the
universal client, wired to refetch that page's TanStack Query data.

New hook lib/nav/useRefreshControl.tsx takes one or more query results
and returns a themed <RefreshControl> (accent-colored spinner, i18n
accessibility label, web-safe). Wired into notes, skills, projects,
profile, experience, network (list + person + org detail), and account.
Pages whose data spans tabs/cards (experience, network, account) lift the
relevant list hooks to the scroll-owning parent so one pull refreshes all
of them via the shared TanStack cache.

Placeholder screens (applications, chat) have no server query and are
skipped. Added common.refresh to the en.json catalog for the control's
accessibility label.

Closes #309

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

📊 Test coverage

Patch coverage: no testable lines changed.

Overall (app/, lib/, db/, excluding UI per ADR-0019):

Metric Value Soft target
Lines 81.6% ≥ 50%
Branches 72.8% ⚠️ ≥ 75%
Functions 91.1% informational

Soft thresholds per ADR-0019. Coverage is informational and does not block merge.

<!-- coverage-comment --> ## 📊 Test coverage **Patch coverage:** no testable lines changed. **Overall** (`app/`, `lib/`, `db/`, excluding UI per ADR-0019): | Metric | Value | Soft target | |---|---|---| | Lines | 81.6% ✅ | ≥ 50% | | Branches | 72.8% ⚠️ | ≥ 75% | | Functions | 91.1% | informational | Soft thresholds per [ADR-0019](docs/adr/0019-coverage-soft-targets.md). Coverage is informational and does not block merge.
james force-pushed 309-pull-to-refresh from a1d2bdb520
All checks were successful
Commits / Conventional Commits (pull_request) Successful in 13s
PR / Static analysis (pull_request) Successful in 46s
PR / OSV-Scanner (pull_request) Successful in 34s
PR / Trivy (image) (pull_request) Successful in 1m52s
PR / pnpm audit (pull_request) Successful in 3m3s
PR / Typecheck (pull_request) Successful in 3m8s
PR / Package age policy (soft) (pull_request) Successful in 25s
PR / OpenAPI (pull_request) Successful in 3m17s
PR / Lint (pull_request) Successful in 3m35s
Secrets / gitleaks (pull_request) Successful in 38s
PR / Client (web export smoke) (pull_request) Successful in 4m9s
PR / Build (pull_request) Successful in 4m32s
PR / Test (sqlite) (pull_request) Successful in 4m46s
PR / Test (postgres) (pull_request) Successful in 4m55s
PR / Coverage (soft) (pull_request) Successful in 4m8s
to 57965318b3
All checks were successful
Commits / Conventional Commits (pull_request) Successful in 15s
PR / Static analysis (pull_request) Successful in 47s
PR / OSV-Scanner (pull_request) Successful in 37s
PR / Trivy (image) (pull_request) Successful in 1m39s
PR / Package age policy (soft) (pull_request) Successful in 16s
PR / OpenAPI (pull_request) Successful in 3m23s
Secrets / gitleaks (pull_request) Successful in 41s
PR / Client (web export smoke) (pull_request) Successful in 3m36s
PR / Typecheck (pull_request) Successful in 3m42s
PR / Test (sqlite) (pull_request) Successful in 3m52s
PR / Test (postgres) (pull_request) Successful in 3m57s
PR / Build (pull_request) Successful in 4m1s
PR / Lint (pull_request) Successful in 4m19s
PR / Coverage (soft) (pull_request) Successful in 3m27s
PR / pnpm audit (pull_request) Successful in 4m32s
2026-06-27 01:40:32 +00:00
Compare
james merged commit 377391c9a8 into main 2026-06-27 01:45:35 +00:00
james deleted branch 309-pull-to-refresh 2026-06-27 01:45:36 +00:00
Sign in to join this conversation.
No description provided.