feat(profile): model legend, today tooltip, newest-first toggle, client logos - #863
Conversation
…nt logos
Four polish fixes on the public profile activity dashboard:
- Usage over time: the legend listed clients/providers while the chart is
model-based. Show the user's top models (by the selected metric) with a
"+N more" cutoff via a new pure `selectLegendModels` helper.
- Contributions: hovering the newest ("today") cell showed no tooltip because
it is the default-selected cell and the hover was suppressed for the selected
cell. Show the tooltip for any in-range cell (2D + 3D); selection/keyboard
behavior is unchanged.
- Contributions: add a localStorage-persisted "Newest first" toggle (2D) that
mirrors the calendar so recent weeks sit on the left. Default follows layout —
reversed on desktop (>=1360px, the 2-column dashboard), chronological on
mobile. Hydration-safe: server + first paint render chronological, then the
resolved value applies after mount.
- Day breakdown: replace the colored client dot in the "Clients and models"
headers with the client logo (SourceLogo), falling back to the dot when a
client has no logo.
Constraint: reversal must not desync month markers or keyboard nav — both route
through the same display-ordered week structure as the cells
Rejected: CSS scaleX(-1) flip | mirrors month-label text and breaks scroll math
Rejected: apply reversal to the 3D isometric view | geometry mirror is risky and
the request targets the 2D card; 3D stays chronological
Confidence: high
Scope-risk: moderate
Directive: keep displayCells/displayMonthMarkers derivation the single source
for both render and keyboard nav so reversed mode can't desync
Not-tested: real-DOM hydration path (no jsdom); covered via pure-helper tests
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8f4aa7552d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| : null, | ||
| [reversed, calendar], | ||
| ); | ||
| const displayCells = displayWeeks?.cells ?? calendar.cells; |
There was a problem hiding this comment.
Re-scroll after reversing the calendar
When the user enables Newest first in an overflowed 2D calendar, this swaps the target date's DOM position, but the scroll effect below only depends on rangeEnd, rangeStart, tabbableDate, and view. If the calendar was already auto-scrolled to the latest day in chronological order, toggling this leaves scrollLeft at the old right edge, so the newly-leftmost newest weeks can be out of view and the user sees the oldest columns instead. Include the resolved ordering (for example reversed/displayCells) in the scroll effect's dependencies or otherwise adjust scroll on toggle.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Good catch — fixed in 85cbd58. The auto-scroll effect now includes reversed in its deps, so toggling Newest first re-runs it and scrolls the newest day's cell (now at the opposite edge) back into view.
| onKeyDown={(event) => | ||
| handleCellKeyDown(cell, event, displayCells) | ||
| } |
There was a problem hiding this comment.
Keep date-key navigation chronological
Passing displayCells here makes keyboard navigation use reversed week chunks when Newest first is enabled, but getContributionFocusDate still interprets ArrowLeft/ArrowRight as adjacent indices and ArrowUp/ArrowDown as ±7 days. In the reversed layout, pressing ArrowRight from a newest-week Saturday jumps to the Sunday of the previous week rather than the next day, and Home/End are inverted, so keyboard inspection no longer follows the documented day/week boundaries. Keep navigation on chronological calendar.cells or update the helper to navigate by visual coordinates explicitly.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 85cbd58. Rather than reconcile the ±1/±7 arithmetic with the mirrored layout, keyboard navigation now stays on the chronological calendar.cells: Arrow keys inspect adjacent calendar days and Home/End hit the true range boundaries regardless of the visual mirror. Newest first is display-only, so the documented a11y contract is preserved.
There was a problem hiding this comment.
All reported issues were addressed across 5 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
…gical Addresses two review findings on the "Newest first" toggle: - The auto-scroll effect didn't depend on `reversed`, so toggling the mirror left scrollLeft at the old edge and the now-leftmost newest weeks could sit off-screen. Add `reversed` to the effect deps so the newest cell is scrolled back into view after a toggle. - Keyboard navigation was fed the reversed display order, which scrambled the Arrow/Home/End semantics (ArrowRight crossed into the previous week, Home/End inverted). Navigate the chronological `calendar.cells` instead: arrows inspect adjacent calendar days and Home/End hit the true range boundaries regardless of the visual mirror, honoring the documented a11y contract. Directive: "Newest first" is display-only — do not route keyboard/date nav through displayCells; keep it chronological Confidence: high Scope-risk: narrow
The client logo in the "Clients and models" headers rendered with
alt={sourceId}, so assistive tech announced the source name twice — once from
the image and once from the adjacent visible client name (the prior colored dot
was decorative). Add an opt-in `decorative` prop to SourceLogo (empty alt) and
use it here so the row keeps a single accessible label.
Confidence: high
Scope-risk: narrow
…#864) The reverse-render toggle from #863 landed on the Contributions calendar, but the request targeted the Usage over time chart — the card that sits in the right-hand column of the >=1360px dashboard grid. Remove the calendar mirroring entirely and mirror the usage chart's time axis instead. The whole per-day pipeline (dates, series values, daily totals) is reversed once in reverseUsageChartData, so pointer hit-testing, keyboard inspection, tooltips, and the date-range labels all follow visual order with no special cases. Trailing averages are computed on chronological data before the mirror; per-provider cost lookups map the visual index back into the chronological days array. Constraint: SSR/first paint must stay chronological (no hydration mismatch); the resolved default applies only after mount Constraint: 30d trailing average must be computed pre-reversal Rejected: reversing only the SVG x-mapping | every index consumer (tooltip, keyboard, provider costs) would need its own mirror logic Rejected: sharing one localStorage key with the removed calendar toggle | stale "0"/"1" from the mistaken feature would silently override the new responsive default Confidence: high Scope-risk: narrow Directive: keep chartData display-ordered; anything indexing the chronological `days` array must go through chronologicalActiveIndex Not-tested: manual toggling while a committed (pinned) inspection is open on a coarse-pointer device
Four polish fixes on the public profile activity dashboard (all frontend).
1. Usage over time — legend shows models, not clients
The chart is model-based (tooltip lists
claude-opus-4-8,gpt-5.5, … each with its own shade) but the legend listed client/provider names (Claude Code, OpenCode, …). New pure helperselectLegendModels(series, limit)ranks the real model series by the selected metric, disambiguates duplicate labels by provider, and the legend now shows the top models with a+N morecutoff. Respects the provider filter automatically.2. Contributions — "today" now shows a hover tooltip
The newest day is the default-selected cell, and the hover tooltip was suppressed for the selected cell (
cell.date === selectedDate) — so hovering today showed nothing. Now the tooltip shows for any in-range cell (2D and 3D), including today/selected. Selection, keyboard nav, and the separate breakdown panel are unchanged. In-range-but-non-selectable cells are no longerdisabled, so they're hoverable.3. Contributions — "Newest first" toggle (localStorage, responsive default)
A persisted checkbox (2D only) mirrors the calendar so recent weeks sit on the left. Default follows layout: reversed on desktop (
>=1360px, the 2-column dashboard) and chronological on mobile; an explicit toggle wins and is stored undertokscale:contributions-newest-first. Implemented via an idempotentreverseContributionCalendarWeeks(reverses whole-week chunks + remaps month markers);displayCells/displayMonthMarkersdrive both the render and keyboard nav so they can't desync. Hydration-safe: server + first client paint render chronological (isMountedgate + SSR-safeuseMediaQuery), then the resolved value applies after mount.4. Day breakdown — client logos in "Clients and models"
Replaced the colored client dot next to each client name with the client logo (
SourceLogo), falling back to the dot when a client has no logo.Verification
tsc --noEmitclean · eslint clean on all changed files · 587 frontend tests pass (62 files, +new pure-helper tests forselectLegendModelsandreverseContributionCalendarWeeks) · productionnext buildpasses.https://claude.ai/code/session_01YTwnnT7dC3tTeLZ5xc4WiZ
Summary by cubic
Polished the public profile activity dashboard with a model-based legend, a “Newest first” 2D calendar option, consistent tooltips, and client logos with better a11y. Improves clarity and navigation without changing data.
New Features
Bug Fixes
Written for commit fef932d. Summary will update on new commits.