Skip to content

feat(mobile): show usage reset countdown on accounts screen#7954

Open
kaynansc wants to merge 3 commits into
stablyai:mainfrom
kaynansc:feat/mobile-usage-reset-countdown
Open

feat(mobile): show usage reset countdown on accounts screen#7954
kaynansc wants to merge 3 commits into
stablyai:mainfrom
kaynansc:feat/mobile-usage-reset-countdown

Conversation

@kaynansc

@kaynansc kaynansc commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

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.:

Resets in 3h 54m (under the 5h bar) · Resets in 6d 7h (under the 7d bar)

The resetsAt timestamps already travel in the accounts.list / accounts.subscribe snapshots (the RPC forwards RateLimitService.getState() unchanged), so this is presentation-only: no protocol, main-process, or desktop changes.

Implementation notes:

  • getResetSummary() is a pure selector in account-usage-state.ts (no RN imports), mirroring the desktop formatResetCountdown/formatDuration copy from src/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).
  • The line only renders when a window actually has 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.
  • A 60s ticker keeps the countdown fresh while the screen sits open, since snapshot pushes only arrive when the desktop's rate-limit poll completes.

Deliberately out of scope (kept the change surgical): the Fable weekly bar, minimax provider support, and the compact home-screen account cards (space there is tight; the accounts screen is the detail view).

Screenshots

image

Testing

  • pnpm lint — mobile pnpm lint (oxlint) and pnpm format:check pass. Root pnpm lint currently fails on main itself (src/main/ipc/notification-authorization-status.ts:71 switch-exhaustiveness, pre-existing and untouched by this PR); verified the failure reproduces on a clean main checkout.
  • pnpm typecheck — root passes; mobile tsc --noEmit passes.
  • 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.
  • Added unit tests for getResetSummary covering: no data → null, single window, both windows joined, exact-hour/exact-day formatting (no 0m/0h remainders), and past timestamps → "resets now".

AI Review Report

Reviewed with Claude Code. Checks performed:

  • Cross-platform (macOS/Linux/Windows): no desktop code touched; the mobile change is platform-neutral React Native (no Platform-specific APIs, no paths, no shortcuts).
  • SSH/remote/local: data arrives via the existing WebSocket RPC snapshot regardless of how the host runs its agents; no assumption of local execution added.
  • Agent/integration compatibility: rendering is provider-neutral — it reads session/weekly windows from ProviderRateLimits and shows nothing when resetsAt is absent, so Claude, Codex, and any future provider behave consistently. No GitHub/GitLab-specific logic involved.
  • Performance: getResetSummary is 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.
  • UI quality: reuses existing theme tokens (typography.metaSize, colors.textMuted) and the row layout already used by rowSubtitle/errorText; numberOfLines={1} guards small screens.
  • Nothing was flagged that required changes beyond the initial design.

Security Audit

  • No new input parsing: resetsAt is a numeric timestamp already delivered by the authenticated host RPC channel; it is only subtracted from Date.now() and formatted. A malicious/corrupt value degrades to "resets now" or a large duration string — no injection surface (React Native Text, no HTML).
  • No command execution, file/path handling, credentials, or IPC surface changes; no new dependencies.
  • No secrets are displayed or logged.

Notes

  • Copy intentionally matches desktop's ("Resets in Xh Ym") but prefixed with the mobile bar labels ("5h"/"7d") since the mobile UI has no per-window headings.
  • Follow-up candidates (not in this PR): Fable weekly window on mobile, usageMetadata/minimax parity in the mobile types.
  • X handle: @kaynansc

https://claude.ai/code/session_01FvjvCsc9QoyQALqvxkvDqQ

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
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 10eefa3c-9ad2-4410-88c0-4e731c972404

📥 Commits

Reviewing files that changed from the base of the PR and between 8adfef4 and 2e7f4ed.

📒 Files selected for processing (4)
  • mobile/app/h/[hostId]/accounts.tsx
  • mobile/src/components/AccountUsage.tsx
  • mobile/src/components/account-usage-state.test.ts
  • mobile/src/components/account-usage-state.ts

📝 Walkthrough

Walkthrough

This change adds reset-countdown text for rate-limit windows in the mobile app. A new getWindowResetLabel helper and internal formatResetPhrase formatter compute relative reset wording from limit timestamps. AccountUsage.tsx re-exports the helper and extends UsageBar with an optional resetText prop and matching layout/styling. accounts.tsx tracks a periodically updated now timestamp and passes computed reset text into UsageBar for both the system-default and per-account rows. Unit tests cover the new formatting logic.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding usage reset countdowns on the mobile Accounts screen.
Description check ✅ Passed The description includes all required template sections and covers the change, screenshots, testing, review, security, and notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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.

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
@kaynansc

kaynansc commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

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.

3 participants