Skip to content

feat(shared): top active squads and popular tags wide feed cards#6087

Open
tomeredlich wants to merge 11 commits into
mainfrom
feat/my-feed-top-squads-popular-tags
Open

feat(shared): top active squads and popular tags wide feed cards#6087
tomeredlich wants to merge 11 commits into
mainfrom
feat/my-feed-top-squads-popular-tags

Conversation

@tomeredlich
Copy link
Copy Markdown
Contributor

@tomeredlich tomeredlich commented May 21, 2026

Summary

  • Adds Top active squads and Popular tags as alternating 2x1 wide cards in My Feed (behind my_feed_multi_card).
  • Includes multi-card grid packing/layout hints, squad join + hover cards on avatars, and tag follow chips with wrap-to-fit layout.
  • Scoped to shared feed only — no explore page or other wide-card variants (topic cluster, most upvoted/discussed, comments preview).

Test plan

  • Enable my_feed_multi_card (on by default in local dev) and open My Feed on a multi-column layout
  • Confirm 2x1 slots alternate Top active squads and Popular tags (dev seeds at indices 21 and 35)
  • Hover squad avatars in the squads card and verify SquadEntityCard tooltip
  • Join a squad from the card when logged out / logged in
  • Follow/unfollow tags in the popular tags card
  • Verify feed still renders normally when the flag is off

Made with Cursor

Preview domain

https://feat-my-feed-top-squads-popular.preview.app.daily.dev

Introduce 2x1 My Feed cards for curated top active squads and popular tags behind the my_feed_multi_card experiment, including grid packing, dev layout seeds, and squad hover cards on avatars.

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
daily-webapp Ready Ready Preview May 24, 2026 7:20am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
storybook Ignored Ignored May 24, 2026 7:20am

Request Review

tomeredlich and others added 5 commits May 21, 2026 10:37
Enable feed v2 highlights in dev, render the highlight card in My Feed,
fix stale marketing CTA imports, and distribute row heights via
ResizeObserver so headlines fit the tall slot without inner scroll.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the header subtitle and row bullets, use production typo-callout
for headlines, and remove the unused accent-dot utility.

Co-authored-by: Cursor <cursoragent@cursor.com>
Bring back the gradient accent dot with the same animated fill as the
header, and clamp grid headlines to two lines for better readability.

Co-authored-by: Cursor <cursoragent@cursor.com>
Persist clicked highlight IDs and switch the accent dot to tertiary fill
and the headline to secondary text so read items are visually distinct.

Co-authored-by: Cursor <cursoragent@cursor.com>
Introduce a 2x1 featured article card with breaking news styling and rotate it with top squads and popular tags in horizontal wide feed slots.

Co-authored-by: Cursor <cursoragent@cursor.com>
@tomeredlich
Copy link
Copy Markdown
Contributor Author

@claude check pr

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 21, 2026

Claude finished @tomeredlich's task in 3m 31s —— View job


PR Review: Top active squads & Popular tags wide cards

Nice work — the layout-hint + grid-packer split is clean and well tested. A few items below worth addressing before merge.


🐛 Bugs / Correctness

1. Copy mismatch: "Popular tags" vs "Most followed tags"packages/shared/src/components/cards/article/PopularTagsGridCard.tsx:209,214
PR title, summary, file name, and getDevSeededLayoutHint comment all say Popular tags, but the rendered <h2> and aria-label say Most followed tags. The HighlightCards test even asserts 'Most followed tags'-style strings nowhere — but the spec-style PR test plan mentions popular tags. Pick one label and use it consistently across copy, slugs, and analytics.
Fix this →

2. useTopActiveSquads fires up to 20 individual GraphQL queriespackages/shared/src/hooks/useTopActiveSquads.ts:66-73
Using useQueries over TOP_ACTIVE_SQUADS_30D (20 handles) results in 20 sequential SQUAD_STATIC_FIELDS_QUERY round-trips per visit. Each query is cached individually, but on first load this is a real network burst for one card. Recommend either:

  • a single backend batch query (sources(handles: [...]) or a dedicated topActiveSquads resolver), or
  • at least lowering the default limit to ~8 (the number actually visible in the card) so we don't fetch invisible rows.
    Fix this →

3. Feature flag description is now stalepackages/shared/src/lib/featureManagement.ts:210

"Enables variable-size cards (1x2, 2x1, 2x2, 3x2)"

But LAYOUT_HINT_VALUES only allows 1x1 | 1x2 | 2x1 and the spec asserts 2x2/3x2 are rejected. Update the JSDoc to match reality.

4. useReadHighlights grows localStorage unboundedlypackages/shared/src/hooks/useReadHighlights.ts:24-32
Each click pushes an ID into a string array persisted to localStorage with no eviction. Over time this entry will swell. Suggest a cap (e.g. keep the last 500) or a periodic prune.

5. SSR/hydration risk in usePopularTagsWrapFitpackages/shared/src/hooks/usePopularTagsWrapFit.ts:83,105
Initial state renders all 40 candidates; the layout effect then trims via flushSync. On the server (no clientHeight) all 40 render, then on the client they collapse — that can cause a visible flash and may produce a hydration mismatch warning depending on style cascade. Consider gating measurement behind a mount flag or rendering only 1x1 of tags until measurement completes.


🧹 Code quality

6. topActiveSquads plumbed through every feed itempackages/shared/src/components/Feed.tsx:736-836, FeedItemComponent.tsx:104-107
Every FeedItemComponent instance now receives topActiveSquads, topActiveSquadsPending, popularTags, renderAsTopSquadsCard, renderAsFeaturedArticleCard, renderAsPopularTagsCard — even though only ~1/40 items actually uses them. Consider passing a single small object or moving the lookup inside FeedItemComponent keyed by index. The current shape will get worse as more wide variants are added.

7. Duplicate variant gating logicpackages/shared/src/components/FeedItemComponent.tsx:399-403

const renderFeaturedArticle = renderAsFeaturedArticleCard && isPostItem;
const renderTopSquads = renderAsTopSquadsCard && isPostItem && !renderFeaturedArticle;
const renderPopularTags = renderAsPopularTagsCard && isPostItem && !renderFeaturedArticle && !renderTopSquads;

The "only one variant at a time" rule is encoded in three lines. Cleaner as a single variant string passed from Feed.tsx (you already compute horizontalWideVariant there). Source of truth in one place avoids drift when adding the next variant.

8. POPULAR_TAGS and TOP_ACTIVE_SQUADS_30D are FE-curated — comments already flag this, but the lists will go stale silently. Worth opening a follow-up ticket to move both to a curated backend feed before GA.

9. formatMembersCount edge casespackages/shared/src/components/cards/article/TopSquadsGridCard.tsx:34-44
count = 1000"1.0k members" (would normally render as "1k"); count = 9999"10.0k". Minor, but easy to fix with a stricter rule (< 10000.toFixed(1).replace(/\.0$/, '')).

10. 'Opensource' label / 'open-source' slug inconsistencyPopularTagsGridCard.tsx:36
All other tags share name/slug casing (Backend/backend, React/react), this one entry is the outlier. Either Open Source/open-source or Opensource/opensource.

11. requestAnimationFrame retry loop with hard-coded < 8 budgetusePopularTagsWrapFit.ts:110-115
The retry-on-zero-height pattern with an 8-frame budget is a workaround that may silently leave the list under-rendered if measurement keeps returning 0 (e.g. card mounted behind display:none). Consider a ResizeObserver-only path that fires when the container actually has a non-zero height.


✅ What looks good

  • feedLayoutHint.ts & feedGridPacker.ts have a clean API surface and solid spec coverage (overlap-free, ordered, density-capped, edge-alternation).
  • useConditionalFeature({ feature: featureMyFeedMultiCard, shouldEvaluate: isMyFeed }) is correctly gated — no wasted GrowthBook evaluations on non-My-Feed pages.
  • useTopActiveSquads is correctly enabled only when hasTopSquadsSlot resolves to true.
  • Reduced-motion fallbacks for the breaking-news gradient and highlight accent dot.
  • Mobile / list / horizontal layouts force 1x1 — correctly preserves the existing single-column feed.
  • The min-h-card + absolute-inset wrapper for the new cards follows the CLAUDE.md guidance about not stretching the row.

Quick test-plan additions

  • Verify <h2> text matches PR copy after fix.
  • Confirm Network tab on first My-Feed visit: how many Source queries fire?
  • Block GrowthBook in DevTools — verify feed still renders as plain 1x1.
  • Reduced-motion OS setting — confirm the breaking-news chip + highlight dot stop animating.

· Branch: feat/my-feed-top-squads-popular-tags

Align popular tags copy, reduce squad query fan-out, cap read highlights storage, simplify wide-card variant wiring, and fix hydration/lint issues in highlight cards.

Co-authored-by: Cursor <cursoragent@cursor.com>
Merge main into the wide feed cards branch, resolve feature flag conflict, restore squad static currentMember for join state, and fix shared lint/typecheck regressions.

Co-authored-by: Cursor <cursoragent@cursor.com>
Re-adds the topContent prop on Feed so MainFeedLayout can render explore
tag chips above the feed. Without it Vercel's Next.js build fails type
checking because MainFeedLayout passes a prop Feed no longer declares.

Co-authored-by: Cursor <cursoragent@cursor.com>
Extend the horizontal-wide featured card to support 3x1 and 4x1 column
spans. Text stays one column wide while the image stretches across the
remaining columns. Dev seeds place all three sizes (2x1, 3x1, 4x1) in
separate density windows so all variants are visible in My Feed at once.
Headline is capped at 4 lines with ellipsis.

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

2 participants