Skip to content

fix(book-club): app-wide 401 re-login, poll deadline TZ, empty-state refresh, action degradation#19

Merged
fabiodalez-dev merged 2 commits into
mainfrom
fix/book-club-review-followups-2
Jul 6, 2026
Merged

fix(book-club): app-wide 401 re-login, poll deadline TZ, empty-state refresh, action degradation#19
fabiodalez-dev merged 2 commits into
mainfrom
fix/book-club-review-followups-2

Conversation

@fabiodalez-dev

Copy link
Copy Markdown
Owner

The four deferred book-club review items (the ones that needed a design call). :app:compileDebugKotlin passes.

  • App-wide 401 → re-loginAuthInterceptor now clears the session token on a 401 to an authenticated request, so SessionStore.authState flips and the nav host routes every screen (Book Club and everything else) back to login instead of stranding the user on a permanent retryable error. This is the central handler the dead isAuthExpired() implied — app-wide, not Book-Club-specific.
  • Poll deadline timezone contractDateFormat.isPast() now compares an ISO-8601 instant as an absolute Instant. The bridge already sends deadlines (closes_at) as UTC …Z via its isoUtc() helper, so poll open/closed gating is now provably correct regardless of device timezone; a bare wall-clock DATETIME still falls back to a best-effort device-local comparison.
  • Empty-state refresh — the "no clubs yet" EmptyState fills the viewport and isn't scrollable, so the PullToRefreshBox gesture never fired on it. Gave it an explicit Refresh button (new book_club_refresh string in all 4 locales). ErrorState already had Retry; the plugin-gone state is terminal by design.
  • Action degradation consistency — an action (join/vote/rsvp/progress) that fails with 404 for a plugin deactivated mid-session now confirmGone() + reloads, so the screen degrades to the friendly "gone" EmptyState the same way the initial-load path already does.

Not included (genuinely low-value micro-polish, left for an interactive UX pass): snackbar de-dup on two identical consecutive messages, openWeb toast on a device with no browser, progress-dialog dismiss-before-save timing.

…ty-state refresh, action degradation

Second batch of book-club review follow-ups (the ones that needed a design call):

- AuthInterceptor: a 401 on an authenticated request now clears the session token,
  so SessionStore.authState flips and the nav host routes every screen back to login
  instead of leaving the user on a permanent retryable error. App-wide (not
  Book-Club-specific) — this is the central handler the dead isAuthExpired() implied.
- DateFormat.isPast(): pin the server timezone contract. An ISO-8601 instant (the
  bridge sends deadlines like closes_at as UTC ...Z via isoUtc()) is now compared as
  an absolute Instant, so poll open/closed gating is correct regardless of device
  timezone. Only a bare wall-clock DATETIME falls back to device-local (best effort).
- BookClubHomeScreen: the "no clubs yet" EmptyState fills the viewport and isn't
  scrollable, so the PullToRefreshBox gesture never fired on it. Gave it an explicit
  Refresh button (new book_club_refresh string, all 4 locales) so a user who joins a
  club on the web can reload. (ErrorState already had Retry.)
- ClubDetailViewModel: an action (join/vote/rsvp/progress) that fails with 404 for a
  plugin deactivated mid-session now confirmGone()+reloads, so the screen degrades to
  the friendly "gone" EmptyState the same way the initial-load path already does.

Verified: :app:compileDebugKotlin passes.
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@fabiodalez-dev, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 32 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e8c22fda-a22e-4563-9cf5-e43d5c3faa7d

📥 Commits

Reviewing files that changed from the base of the PR and between 9ddc37f and 9e8e60b.

📒 Files selected for processing (11)
  • app/src/main/java/com/pinakes/app/data/network/AuthInterceptor.kt
  • app/src/main/java/com/pinakes/app/ui/common/DateFormat.kt
  • app/src/main/java/com/pinakes/app/ui/screens/bookclub/BookClubHomeScreen.kt
  • app/src/main/java/com/pinakes/app/ui/screens/bookclub/BookClubHomeViewModel.kt
  • app/src/main/java/com/pinakes/app/ui/screens/bookclub/BookClubUi.kt
  • app/src/main/java/com/pinakes/app/ui/screens/bookclub/ClubDetailScreen.kt
  • app/src/main/java/com/pinakes/app/ui/screens/bookclub/ClubDetailViewModel.kt
  • i18n/de.json
  • i18n/en.json
  • i18n/fr.json
  • i18n/it.json
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/book-club-review-followups-2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…progress-dialog timing

The three low-severity UI items deferred from the review:

- Snackbar: keyed the show LaunchedEffect on a monotonic nonce (bumped on every
  post) instead of the resolved message string, so two identical consecutive
  messages (e.g. voting twice → "Vote saved") both surface instead of the second
  being silently swallowed. Both the home and detail screens.
- openWeb(): a blank URL or a device with no browser (ActivityNotFoundException)
  was a silent no-op; now shows a Toast (new book_club_no_browser string, 4 locales).
- ProgressDialog: no longer dismissed the instant onSave fires — it stays open
  showing its `saving` state until the network round-trip clears progressBookId,
  so the loading state is actually reachable and a fast save no longer flashes shut.

Verified: :app:compileDebugKotlin passes.
@fabiodalez-dev fabiodalez-dev merged commit 817e00f into main Jul 6, 2026
1 of 2 checks passed
@fabiodalez-dev fabiodalez-dev deleted the fix/book-club-review-followups-2 branch July 6, 2026 20:10
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