Skip to content

feat(share): share controls on Happening Now (page, topic, highlight)#6355

Draft
tsahimatsliah wants to merge 2 commits into
claude/website-sharing-visibility-be6b32from
claude/share-happening-now
Draft

feat(share): share controls on Happening Now (page, topic, highlight)#6355
tsahimatsliah wants to merge 2 commits into
claude/website-sharing-visibility-be6b32from
claude/share-happening-now

Conversation

@tsahimatsliah

@tsahimatsliah tsahimatsliah commented Jul 22, 2026

Copy link
Copy Markdown
Member

Part of the sharing-visibility initiative. Builds on PR 1 (claude/website-sharing-visibility-be6b32) — base this branch on it, not main.

What changed

Three levels of share/copy on the Happening Now surface, all reusing the PR 1 ShareActions primitive:

Level Where Control
Page HighlightsPage.tsx header, right of the "Happening Now" title ShareActions icon trigger, aria-label="Share Happening Now". Link tracks the active tab (/highlights, /highlights/all, /highlights/<channel>).
Topic DigestCTA.tsx, left of the digest notify button Copy control, aria-label="Copy link to <displayName>", links to that channel's tab.
Highlight HighlightItem.tsx, next to "Read more" in the expanded body Copy control, aria-label="Copy link to this highlight", links to post.commentsPermalink.

commentsPermalink was verified against the typed model: it is a required string on PostHighlightFeed['post'] and is selected by POST_HIGHLIGHT_FEED_FRAGMENT. It's already used directly as a share href elsewhere (ShareBar).

New HighlightShareButton.tsx is a thin logging wrapper around ShareActions so all three levels emit an identically shaped event with Origin.HappeningNow (added by PR 1 — not duplicated) plus a level discriminator. It uses the generic LogEvent.ShareLog: a highlight is not a full Post here (the feed query returns only id + permalink), so SharePost would emit events missing every standard post property. lib/log.ts is untouched.

Avoiding triple-rendering

The composition is:

HighlightsPage
├─ header  ......................... page-level control (1×, always)
└─ TabContainer  (shouldMountInactive = false → only the ACTIVE tab mounts)
   ├─ MajorHeadlinesTab → HighlightFeedList → HighlightItem[]
   ├─ AllHighlightsTab  → HighlightFeedList → HighlightItem[]
   └─ ChannelTab
      ├─ DigestCTA (only when channel.digest)  ... topic-level control (1×)
      └─ HighlightFeedList → HighlightItem[]
  • TabContainer defaults to shouldMountInactive: false and HighlightsPage doesn't override it, so only one tab subtree mounts — never N DigestCTAs.
  • DigestCTA is rendered from exactly one place (ChannelTab) and is not composed by HighlightItem or HighlightFeedList. Both HighlightItem and DigestCTA have no render sites outside components/highlights/.
  • The item-level control only renders inside the expanded body, and only one highlight is expanded by default (the ?highlight= route param), so the three levels do not stack into a row of share buttons. A test asserts exactly one control per level on a channel tab.

Flag

share_happening_now, default false, appended at the very end of featureManagement.ts. Evaluated once in HighlightsPage via useConditionalFeature with shouldEvaluate: useSharingVisibility().isEnabled, then threaded down as a resolved showShare / shareLink prop — GrowthBook is not re-evaluated per highlight row, and HighlightItem stays provider-light.

Flag-off is byte-identical to the PR 1 branch: every new node is gated on the new prop, the Read more link and the digest notify <span> keep their original markup/classes, and the digest copy only gets min-w-0 flex-1 truncate when the share control is actually rendered.

Storybook

packages/storybook/stories/components/HappeningNowShare.stories.tsxAllLevels, FlagOff, PageLevel, TopicLevel, ItemLevel, MobileWidth. Because the components take a resolved boolean prop rather than reading the flag themselves, the known-broken mock/gb.ts (value || 'control' makes falsy flags read as truthy) is not in the path — the FlagOff story is a real control.

Verification

  • node ./scripts/typecheck-strict-changed.js — pass
  • pnpm --filter shared lint — pass (webapp untouched)
  • NODE_ENV=test pnpm --filter shared test — 295 suites / 1991 tests pass
  • NODE_ENV=test pnpm --filter webapp test — 44 suites / 297 tests pass

New tests assert: copy writes to the clipboard and pushes the ✅ Copied link to clipboard toast; a single tap calls navigator.share on mobile; exactly one control renders per level with no duplication; and flag-off renders none of the three while keeping "Read more" intact.

🤖 Generated with Claude Code

Preview domain

https://claude-share-happening-now.preview.app.daily.dev

Adds three levels of share/copy on the Happening Now surface behind the
`share_happening_now` flag (AND the `sharing_visibility` master switch):

- page: share popover next to the "Happening Now" title
- topic: copy control in the channel's `DigestCTA`
- highlight: copy control next to "Read more" in an expanded `HighlightItem`

All three reuse the PR 1 `ShareActions` primitive through a thin logging
wrapper so every level emits the same `Origin.HappeningNow` payload.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 22, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
daily-webapp Ready Ready Preview Jul 22, 2026 7:10pm
storybook Building Building Preview Jul 22, 2026 7:10pm

Request Review

Page and topic levels now pass a referral cid like every comparable surface,
and trigger labels move to the Share verb family since the desktop trigger
opens a share popover rather than copying.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.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.

1 participant