Add pull-to-refresh to each page #309

Closed
opened 2026-06-27 00:38:04 +00:00 by james · 0 comments
Owner

Add a "pull to refresh" gesture to every content page in the universal client (apps/client) so users can refetch the page's server data by pulling down.

Scope

Each page that renders server data via TanStack Query hooks (@carol/api-client):
app/(app)/ → applications, chat, experience, notes, skills, profile, network, projects, account, and the detail screens network/[id], network/orgs/[id].

Approach

  • Use React Native's RefreshControl on each page's scrollable container (ScrollView / FlatList / KeyboardAwareScrollView), wired to the page's query: refreshing = the query's isRefetching (or a local flag), onRefresh = refetch(). For pages with multiple queries, refetch all and aggregate the refreshing state.
  • Factor the wiring into a small shared helper/hook (e.g. useRefreshControl(...queries) returning a <RefreshControl> or its props) so every page is consistent — reuse, don't copy-paste per screen.
  • Native is the primary target (the pull gesture). On web RefreshControl is effectively inert, which is fine; don't regress web scrolling.
  • Theme the spinner with the accent token (theme.tokens.accent) where the control exposes color props.

Conventions

  • No hardcoded user-facing strings; RefreshControl has no visible label normally, but any a11y label goes through the i18n catalog.
  • typecheck + lint pass.

Note

Shares files with #308 (back-nav). Sequence after #308 to avoid edit collisions, or rebase whichever merges second.

Add a "pull to refresh" gesture to every content page in the universal client (`apps/client`) so users can refetch the page's server data by pulling down. ## Scope Each page that renders server data via TanStack Query hooks (`@carol/api-client`): `app/(app)/` → applications, chat, experience, notes, skills, profile, network, projects, account, and the detail screens `network/[id]`, `network/orgs/[id]`. ## Approach - Use React Native's `RefreshControl` on each page's scrollable container (`ScrollView` / `FlatList` / `KeyboardAwareScrollView`), wired to the page's query: `refreshing` = the query's `isRefetching` (or a local flag), `onRefresh` = `refetch()`. For pages with multiple queries, refetch all and aggregate the refreshing state. - Factor the wiring into a small shared helper/hook (e.g. `useRefreshControl(...queries)` returning a `<RefreshControl>` or its props) so every page is consistent — reuse, don't copy-paste per screen. - Native is the primary target (the pull gesture). On web `RefreshControl` is effectively inert, which is fine; don't regress web scrolling. - Theme the spinner with the accent token (`theme.tokens.accent`) where the control exposes color props. ## Conventions - No hardcoded user-facing strings; RefreshControl has no visible label normally, but any a11y label goes through the i18n catalog. - typecheck + lint pass. ## Note Shares files with #308 (back-nav). Sequence after #308 to avoid edit collisions, or rebase whichever merges second.
james closed this issue 2026-06-27 01:45:36 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
james/carol#309
No description provided.