feat(layout-v2): label rail icons and pin streak/cores/reputation#6177
Open
tsahimatsliah wants to merge 140 commits into
Open
feat(layout-v2): label rail icons and pin streak/cores/reputation#6177tsahimatsliah wants to merge 140 commits into
tsahimatsliah wants to merge 140 commits into
Conversation
Make the v2 desktop rail legible and keep gamification signals at a glance:
- Add a text label under every rail category icon; widen the rail 64px->80px
and update the coupled content offset, separator, and toggle positions.
- Rename the Game Center rail category to "Quests".
- Pin a compact streak / cores / reputation cluster to the rail so the stats
stay visible regardless of collapsed/expanded state or selected panel.
- Label the rail notifications bell ("Alerts") to match.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
largeNumberFormat returns string | null; widen RailSlot value type to match (mirrors SidebarHeaderStats) so the strict typecheck passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Reduce the rail's horizontal padding (px-2 -> px-1.5) so it feels less bulky. - Remove the Profile tab from the top category list and relocate it to the bottom of the rail (below the settings icon) as the profile avatar, with the same click/panel navigation the tab had. - Move the streak / cores / reputation cluster below the avatar. - Drop the avatar + name + stats block from the expanded Home panel (the stats now live only on the rail; create-post action stays). - Extract StreakPopover into its own file and delete the now-unused SidebarHeaderStats component. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Make every rail button's hover the same width; fix the Alerts bell that collapsed to content width (bare wrapper div). Search stays icon-only with the shortcut hint outside the hover. - Add account-synced compact mode via the sidebarCompact flag (stored in the settings flags bag, no backend migration): hides the rail labels and search hint and narrows the rail back to its icon-only width. Toggle on the rail (utilities group) and a switch in Settings > Appearance (v2 only). MainLayout content offset mirrors both width sets. - Move the profile avatar to the very bottom, below the stats cluster. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Remove the rail's compact/hide-labels toggle button (menu icon); compact
mode stays available from Settings > Appearance.
- Give the Home expanded panel the same title header ("Home") as every other
dedicated panel, replacing the New post button (still available on the rail).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Remove the Discover rail category; surface Explore from the Home panel (after Following) and map its sub-routes (/posts, /tags, /sources, /users, /discussed) to the Home category for active highlighting. Step 1 of the Explore restructure — the dedicated pages become Explore tabs next. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Rail order is now Home, Squads, Alerts, Quests, Saved, Settings (bell moved before Quests; Settings lifted from the bottom utilities into the top nav as a labeled tab). - Combine the streak / cores / reputation cluster and the profile avatar into one bordered card at the bottom (stats on top, avatar below), and enlarge the stats for prominence. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When the rail is too short to fit every nav item, the lowest-priority items fold into the Settings button, which becomes a 3-dots "More" dropdown — fold order Saved → Quests → Alerts; Home, Squads and New post always stay. The fold point is measured against the nav list's height via ResizeObserver, so it tracks the viewport like Slack's sidebar. Extracted a renderCategoryTab helper to share tab markup between the rail and the More menu. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Stack each rail stat as icon-on-top / value-below to match the nav items. - Remove the dark filled card (border + background + dividers) around the stats and profile avatar so the cluster reads bright and open on the rail. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a shared ExploreSectionTabs primary navbar (Explore / Tags / Sources / Leaderboard / Discussions) so the pages folded out of the old Discover hub stay one click apart: - Explore feed header (MainFeedLayout) stacks the section tabs above the existing sort tabs (Popular / upvotes / comments / date / best) — the grouped two-level layout. - Tags, Sources and Leaderboard pages render the section tabs in their PageHeader so the hub persists across the directory pages. Discussions persistence (its header routes through the feed heading) is a follow-up. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reframe the squad favorite as a "pin" in v2 (reuses favoritedAt / toggleFavoriteSource — no backend change): - SquadFavoriteButton shows a pin icon + "Pin/Unpin" label in v2 (v1 keeps the star/favorite look). - New PinnedSection lists the user's pinned squads under a "Pinned" header in the Home panel; renders nothing when empty. - NetworkSection no longer floats pinned squads to the top of the Squads list in v2 (plain alphabetical order) since they now live in the Pinned section. - Add sidebarPinnedExpanded settings flag for the section's collapse state. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
SquadFavoriteButton is a shared, provider-light button; reading useLayoutVariant() (which needs AuthContext) crashed its unit test. Take an `asPin` prop instead and have the v2 callers (NetworkSection, PinnedSection) pass it, so the button stays context-free and v1 keeps the star/favorite labels. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Keep the pin icon hover-only even when a squad is pinned (the Pinned header already conveys the state), so the column isn't busy. v1 favorites are unaffected. - Always render the "Pinned" section header (even when empty) so users discover the feature. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a "Recent" section listing the last 5 non-post pages the user visited (profiles, feeds, tags, sources, etc.). Post permalinks (/posts/[id]) are skipped — they belong to reading History. - recentPages.ts: tiny localStorage-backed external store. - useRecentPages / useRecordRecentPages: read via useSyncExternalStore; record route changes (gated to v2) reading the settled document.title. - RecentSection mounted in the Home panel under Pinned; hidden when empty. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Slack-style profile menu replaces the Profile sidebar panel: - Bottom-rail avatar opens an InteractivePopup with Your profile, Analytics, Jobs, Settings, DevCard (Cores wallet omitted — the stats cluster links there). New SidebarProfileMenu popup position. - Remove the Settings rail tab; the overflow "More" is now a standalone 3-dots button (no longer the Settings anchor) and no longer lists Settings. - Profile sub-routes resolve to their natural category (devcard → Settings); updated sidebarCategory tests accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…b row Replace the stacked sort tabs on the Explore feed header with a right-aligned "Sort" dropdown next to the section tabs — sorting a feed isn't navigating to a sibling page, so a dropdown reads cleaner (Reddit/GitHub pattern). Each sort stays its own route; the date-range control still shows for the upvotes/comments sorts. v1 inline explore header is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Set the streak component back to the variation we liked: a bordered box (54x76, frame radius 19 / fill 16) wrapping the 40px avatar at top and the flame+number chip at the bottom, two distinct hover buttons. Keeps the photo-friendly avatar hover (brighten+scale) and the chip-anchored tooltip from later fixes. State visuals are unchanged (driven by useStreakRingState). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- raise the rail top padding (pt-1.5 -> pt-3) so the streak tile's top gap matches the ~13px it has on each side - reduce the tile's bottom margin (mb-3 -> mb-2) to bring the search icon a bit closer Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rder Approach #2: the box grows a little (54->62px) and the avatar is centred, giving the flame+number room at the bottom without touching the frame. State visuals unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- root cause of the non-square avatar: the ProfilePicture <img> is display:inline,
so its baseline descender made the wrapping button taller than wide. Force the
image to `block` (both streak + no-streak branches).
- root cause of the broken tooltip: the shared Tooltip bakes in
collisionPadding {top:75} (old top-header leftover); the avatar sits ~20px from
the viewport top so that no-go zone shoved the tooltip down and mangled the
arrow. Pass RAIL_TOOLTIP_COLLISION_PADDING on the avatar + chip tooltips.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Use border-subtlest-quaternary (the soft divider between the rail icons and the panel) for the calm streak states instead of the slightly stronger -tertiary. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The flame + number now sit on the box's bottom border and break through it like a fieldset legend — the chip uses the sidebar background to mask the line where it crosses, so a long number just opens a wider gap. Box is shorter (54x56, frame radius 16 / fill 13); all state visuals stay driven by useStreakRingState. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Set the rail top padding to 13px to exactly match the tile's side gap (54px tile centred in 68px content = 7px + 6px px-1.5), so top = left = right. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…r glow - useInteractivePopup now accepts a group; popups in the same group close each other on open (needed because wrapHandler stops propagation, so opening one popup never reaches the others' outside-click listeners). Wire support, the profile menu and the reading-streak popover into one group so only one shows at a time. - avatar hover is now a plain scale-up (removed hover:brightness-110 glow). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- box 56 -> 66 so the legend chip sits well below the avatar instead of crowding it (chip stays on the bottom border, just lower) - calm border quaternary (8% alpha, near-invisible) -> tertiary (20%) so the ring reads against the dark surface - chip keeps bg-background-default (the exact sidebar background) so it masks the border seamlessly Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- extract the streak indicator's "border legend" visual into a presentational StreakRing component (packages/shared); it takes `state` as a prop and never calls the hook, so it stays provider-light. State visuals come from useStreakRingState's now-exported class maps, so the rail and Storybook render identically. - SidebarDesktopV2 now renders <StreakRing> and passes the interactive avatar button + chip props; no behaviour change. - add Components/Sidebar/StreakRing story: a Playground (state/count/hasReadToday controls) and an AllStates grid covering every stage, on the dark rail bg. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Brings the streak chip a little closer to the avatar. The chip already uses bg-background-default — the exact sidebar background — so it stays seamless. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The new StreakRing story makes typecheck_strict_changed run the storybook tsc, which follows shared's icon barrel into the SVGR `*.svg` imports. The storybook package had no `*.svg` ambient declaration (only packages/shared does), so every icon failed TS2307 and the changed icons (Help, NewPost) tripped the gate. Add a storybook svg.d.ts mirroring shared/custom.d.ts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- rest day (frozen): flame icon is now filled (keeps the blue colour) - celebration flame + number now use the read-today pink (was white) - earn pop reworked: only the border animates — it pops bigger while shifting gray -> pink, then settles back to default size; the fill fades to a pink tint on the way back with no size change (new streak-earn-border / streak-earn-fill keyframes). transition-colors on frame + fill smooths the settle. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The v2 rail isn't bg-background-default — at laptop+ it's overridden to the tinted page colour (color-mix surface-secondary 3% over background-default). The chip used pure background-default, so it read as a slightly different shade. Use the same color-mix on the chip (and the Storybook decorator) so it masks the border seamlessly and blends with the rail. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…out shift) The streak tile only rendered once the streak query resolved (isEnabled required the fetched data), so it swapped in from the small avatar-only fallback — shifting the rail. Now: - useReadingStreakSummary derives isEnabled from settings (logged in + not opted out), known before the data loads, and exposes isLoading. - StreakRing renders at full size immediately and shows a same-size skeleton (neutral border + placeholder flame/number) until the data arrives. - celebration pop is gated on !isLoading so the loading->loaded settle never fires a false earn animation. - Storybook: isLoading control + a Loading story. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Earn pop now feels like a gong: sharp fast strike (border snaps bigger + gray->pink by 20%), then rings out smoothly back to default size with the pink fill in harmony. Faster (1.5s -> 0.7s), no plateau, and CELEBRATION_MS 1800 -> 800 so it never holds before settling. - Urgency tooltip: auto-opens for at_risk AND critical (was critical-only, 5s timer) and stays open until the user hovers the streak, then reverts to hover-only; re-arms each time the streak re-enters an urgent state. - The StreakRing skeleton / no-shift work and all earlier Storybook changes are shared, so they're already live in the rail (webapp + extension). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… tooltip - Earn pop is now a smooth single "breathe": ease-in-out, gentle 1.16 expand + settle, faster (0.7s -> 0.5s, CELEBRATION_MS 800 -> 600), no snappy attack or lingering tail — fluid with the gray->pink colour shift. - Urgency tooltip is critical-only again: auto-opens for ~5s when the streak turns critical, hides on the 5s timer or as soon as the user hovers the streak; re-arms on re-entering critical. (Dropped the at-risk auto-open.) - Storybook: add a CriticalWithTooltip story so the urgency tooltip design is visible (forced open), plus the chipTooltip/chipTooltipOpen controls. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The CriticalWithTooltip story is the only one that mounts the shared Tooltip, which reads the request protocol via useQueryClient — without a QueryClientProvider that throws, so the story errored. Add the provider decorator (matching Tooltip.stories). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Swap the slow ease-in-out breathe for a snappy pop: the border strikes up fast with overshoot (scale 1.25), rebounds slightly past its rest size (the gong vibration), then settles — ease-out, 0.45s. CELEBRATION_MS 600 -> 550. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The chip now uses the same colour that sits behind the avatar for each state (opaque, never transparent): calm states keep the rail tint, while freeze / at-risk / critical / earned use the matching -flat tint (freeze is the exact same blueCheese-flat as its fill). So the chip reads as part of the coloured state instead of a separate neutral box. transition-[transform,background-color] fades the chip colour smoothly on state changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
At rest the chip stays the neutral rail tint (masking the border); on hover it shifts to the colour behind the avatar — freeze -> blueCheese-flat, at-risk -> bun-flat, critical -> ketchup-flat, earned -> bacon-flat (calm states get a subtle surface-hover). Reverts the always-on colour to a hover-only change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Shorten the earn-pop strike to 0.3s (was 0.45s) and CELEBRATION_MS 550 -> 400 so it pops and settles quickly with no hold. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A side-by-side comparison of celebration animations at different durations and easings (punch+rebound, quick punch, snap, spring/back-out, gong ring) with a Replay button, to dial in the perfect earn-pop feel. Uses inline keyframes so the timing is accurate even when the running Storybook serves a stale tailwind config (tailwind config changes don't hot-reload). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the mixed-easing variations with the same punch+rebound pop at 6 durations (0.15 / 0.3 / 0.45 / 0.6 / 0.8 / 1s) to compare speed only. Drop the now-unused punch/spring/gong keyframes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Set the earn pop to 0.6s and rework the fill timing: the pink stays clear while the border strikes up to its peak (0->25%), then washes in from that point to the end as the border rebounds and settles — instead of flashing in at the peak. CELEBRATION_MS 400 -> 700 to cover the longer pop. Mirror the timing in the Storybook earn-pop lab. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Remove popClassByState (an all-empty-string map) and the popClassName return field/type — read by no consumer since the earn pop moved to a border-only animation. - Remove the isUrgent return field/type — no consumers. - Remove weekProgress and the eager 30-day reading-history query that only fed it. The query key is shared (ReadingStreakPopup fetches it on demand), so this just drops a wasted 30-day fetch that ran for every logged-in user, plus the now-unused WEEK_LENGTH/imports. No behaviour change — all removed symbols were unreferenced. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Addresses the top council feedback on the new reading-focused layout (v2): "everything is hidden, you have to remember the icons, and streak/cores/reputation aren't visible."
SidebarRailStatssits at the bottom of the always-visible rail, so the loved gamification signals stay at a glance regardless of whether the context panel is collapsed/expanded or which category is selected. Previously these only rendered in the expanded Home panel. Reuses the existing handlers (streak popover, wallet, reputation docs); the streak popover was generalized to open to the right (bottom-anchored) so it doesn't clip near the viewport bottom.Notes
layout_v2(laptop+).InteractivePopupline 142 (laptop:left-16) is shared with v1, so it's untouched to avoid a v1 regression;RAIL_HOVER_PROFILE_ALIGN_OFFSETmay want minor re-tuning now that rail items are taller (cosmetic, collapsed hover only).Testing
tscclean on all changed files; eslint clean; sidebar specs pass (16/16).🤖 Generated with Claude Code
Preview domain
https://claude-strange-jang-4a3ea2.preview.app.daily.dev