feat(share): surface a copy-link control on profile headers#6354
Draft
tsahimatsliah wants to merge 3 commits into
Draft
feat(share): surface a copy-link control on profile headers#6354tsahimatsliah wants to merge 3 commits into
tsahimatsliah wants to merge 3 commits into
Conversation
Adds a dedicated share control to the profile header instead of burying it in the "..." options menu. - Own profile: sits next to "Edit profile". - Public profile: fills the slot the (inapplicable) edit button used to reserve, so the layout height is unchanged. - Stays well away from Follow (different card region, Float icon vs. the filled primary CTA) so the two intents don't read as one control group. - The pinned mobile profile header shows it only while pinned, where the profile card has scrolled away — otherwise there would be two identical copy buttons on screen. Built on the shared `ShareActions` primitive from PR 1, so mobile taps straight through to the native share sheet and desktop opens the network popover. Gated by `share_profile` plus the `sharing_visibility` master flag. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Reconciles the CustomFeedOptionsMenu API with the tags/sources branch: shareProps stays required (no empty-link fallback into useShareOrCopyLink) and surfaces that promote share to a visible control pass hideShare instead. File is now byte-identical on both branches so the stack merges cleanly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Evaluate the per-topic flag only once sharing_visibility passes, so control users are never bucketed into the experiment. Matches the other topic gates. Also types the menu spec helper now that shareProps is required again. 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.
Part of the sharing visibility initiative. Builds on PR 1 (#6343) — base branch is
claude/website-sharing-visibility-be6b32, notmain.What changed
The share action on a profile lived only inside the
...options menu, and the owner's only share affordance (thePublic profile & URLwidget) islaptop:hidden, so a signed-in user on desktop had no way to share their own profile at all. This promotes it to a real control.ProfileHeader.tsx— the canonical placement (all breakpoints, both profile types)invisiblethere today purely to hold the row's height), so the layout height is unchanged and no dead placeholder is left behind.profile/Header.tsx— the pinned mobile barsticky). Unpinned, the profile card directly below owns it; rendering both would put two identical copy buttons on one screen....menu here.ProfileActions.tsx— share promoted out of its...menu too; the new button sits directly above it on the same card.CustomFeedOptionsMenu.tsx—sharePropsis now optional; omitting it drops theShareentry. Backwards compatible, no other call site changes. This is the only shared-component touch outsideprofile/.New
profile/ProfileShareButton.tsx— thin wrapper over PR 1'sShareActionsthat pins the share text,ReferralCampaignKey.ShareProfile, and the analytics payload so every profile surface behaves identically. Mobile = single tap to the native share sheet; desktop = the network popover.hooks/profile/useShareProfileEnabled.ts— resolves the per-topic flag and the master kill-switch in one place.Research principle #6 — share stays distinct from Follow
Share is a
Floaticon control in the header's top-right utility slot; Follow is the filled primary CTA further down the card, insideProfileActions. Different region, different weight, different variant — they never sit in the same control group. In the pinned bar,ml-1separates the utility icon from the Follow group.Logging
Reuses the existing
LogEvent.ShareProfile(the event already emitted by the menu item and the owner share widget, so metrics stay comparable) withtarget_type: TargetType.ProfilePageandextra: { provider, origin: Origin.Profile }. No newOriginvalue was needed.Flag
share_profile, defaultfalse, appended at the end offeatureManagement.ts. Gated viauseConditionalFeatureanduseSharingVisibility(). Flag-off is pixel-identical to the PR 1 branch — asserted in Jest (ProfileHeader.spec.tsx: the invisible edit placeholder is preserved, no share control renders anywhere).OG image — deferred, on purpose
A per-profile unfurl card (mini dev-card with handle + stats) would make a shared profile land much harder. It is not in this PR:
packages/webapp/pages/image-generator/(devcards/[userId].tsx,badges/[badgeId].tsx,id="screenshot_wrapper", ISR).image-generator/profiles/[userId].tsxroute is only half the work: the backend screenshot service needs a route registered for it, andgetProfileSeoDefaultsneeds to emit the resultingog:image. That is a cross-repo dependency with its own rollout.Shipping the affordance now and the image as a follow-up keeps this PR reviewable, per the brief's explicit guidance to defer rather than half-build.
Backend dependencies
None for this PR. The deferred OG image needs a screenshot-service route (see above).
Verification
node ./scripts/typecheck-strict-changed.js— clean for every file this PR adds or rewrites. The remaining reported errors (CustomFeedOptionsMenu.tsx:51feeds.edges.length,ProfileActions.tsxuser.username) are pre-existing on the base branch; confirmed by reading the same expressions out oforigin/claude/website-sharing-visibility-be6b32, untouched by this diff.pnpm --filter shared lint— pass.NODE_ENV=test pnpm --filter shared test— 297 suites / 1997 tests pass.NODE_ENV=test pnpm --filter webapp test— 44 suites / 297 tests pass.pnpm --filter storybook lintnot run (missing eslint binary, pre-existing repo issue).buildnot run, per instructions.Tests added
ProfileShareButton.spec.tsx— copy writes the permalink to the clipboard and raises the✅ Copied link to clipboardtoast; native share callsnavigator.sharewith the share text + link and never touches the clipboard; desktop reveals the network list; both labels (Share your profile/Share @handle's profile) are asserted for a11y.ProfileHeader.spec.tsx— flag-off keeps the invisible edit placeholder and renders no share control; flag-on fills the slot on public profiles and sits beside Edit on the owner's.CustomFeedOptionsMenu.spec.tsx—Shareis listed withsharePropsand dropped without them.Storybook
Components/Share/ProfileShareButton— public/own labels, network list, copying state, and the button in place in both header variants.HeaderControlis the flag-off story; it holdsFeaturesReadyContextas not-ready, because the repo-widemock/gb.tscoerces afalsedefault to the truthy string'control'and would otherwise render the variant.Open questions
Sharefrom the...menus — intentional per the brief ("promote out of the menu where it makes sense"), but it does mean the menu loses an entry some users may have learned. Easy to keep both if we'd rather not move anyone's cheese mid-experiment.Check out {name}'s profile on daily.dev(matching the current menu copy) andCheck out my profile on daily.devfor the owner. Worth a copy pass?🤖 Generated with Claude Code
Preview domain
https://claude-share-profile.preview.app.daily.dev