feat(mobile): show usage reset countdown on accounts screen#7954
feat(mobile): show usage reset countdown on accounts screen#7954kaynansc wants to merge 3 commits into
Conversation
Surface the rate-limit reset time ("5h resets in 3h 54m · 7d resets in
6d 7h") under the usage bars on the mobile accounts screen, matching the
desktop status-bar tooltip copy. The resetsAt timestamps already arrive
in the accounts.subscribe snapshot; this only adds the presentation.
Claude-Session: https://claude.ai/code/session_01FvjvCsc9QoyQALqvxkvDqQ
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThis change adds reset-countdown text for rate-limit windows in the mobile app. A new 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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. Comment |
Drop the redundant "5h/7d" prefixes — each countdown now renders under
its own bar ("Resets in 3h 54m"), matching the desktop tooltip copy
exactly.
Claude-Session: https://claude.ai/code/session_01FvjvCsc9QoyQALqvxkvDqQ
|
@coderabbitai full review |
✅ Action performedFull review finished. |
Summary
The mobile accounts screen already shows Session ("5h") and Weekly ("7d") usage bars per account, but not when those windows reset — information the desktop status-bar tooltip already surfaces ("Resets in 3h 54m"). This adds a muted one-line countdown under the usage bars, e.g.:
The
resetsAttimestamps already travel in theaccounts.list/accounts.subscribesnapshots (the RPC forwardsRateLimitService.getState()unchanged), so this is presentation-only: no protocol, main-process, or desktop changes.Implementation notes:
getResetSummary()is a pure selector inaccount-usage-state.ts(no RN imports), mirroring the desktopformatResetCountdown/formatDurationcopy fromsrc/renderer/src/components/status-bar/tooltip.tsx. Duplicated rather than imported because the mobile bundle must not pull in renderer code (same convention as the existing types in that file).resetsAt, so providers whose fetcher couldn't resolve a timestamp (e.g. PTY-parse fallbacks that fail to parse the reset text) degrade to today's UI.Deliberately out of scope (kept the change surgical): the Fable weekly bar,
minimaxprovider support, and the compact home-screen account cards (space there is tight; the accounts screen is the detail view).Screenshots
Testing
pnpm lint— mobilepnpm lint(oxlint) andpnpm format:checkpass. Rootpnpm lintcurrently fails onmainitself (src/main/ipc/notification-authorization-status.ts:71switch-exhaustiveness, pre-existing and untouched by this PR); verified the failure reproduces on a cleanmaincheckout.pnpm typecheck— root passes; mobiletsc --noEmitpasses.pnpm test— full mobile suite: 177 files, 1272 passed / 2 skipped. Root desktop suite not run (no desktop code touched).pnpm build— not run; change is mobile-only (Expo app), desktop build unaffected.getResetSummarycovering: no data →null, single window, both windows joined, exact-hour/exact-day formatting (no0m/0hremainders), and past timestamps → "resets now".AI Review Report
Reviewed with Claude Code. Checks performed:
session/weeklywindows fromProviderRateLimitsand shows nothing whenresetsAtis absent, so Claude, Codex, and any future provider behave consistently. No GitHub/GitLab-specific logic involved.getResetSummaryis O(1) string work at render time; the 60s interval is a single timer for the screen and is cleaned up on unmount. Flagged and verified: the ticker re-renders the whole screen once a minute, which is negligible for this screen's size.typography.metaSize,colors.textMuted) and the row layout already used byrowSubtitle/errorText;numberOfLines={1}guards small screens.Security Audit
resetsAtis a numeric timestamp already delivered by the authenticated host RPC channel; it is only subtracted fromDate.now()and formatted. A malicious/corrupt value degrades to "resets now" or a large duration string — no injection surface (React NativeText, no HTML).Notes
usageMetadata/minimaxparity in the mobile types.https://claude.ai/code/session_01FvjvCsc9QoyQALqvxkvDqQ