feat(share): share my streak from the reading streak popup#6358
Draft
tsahimatsliah wants to merge 2 commits into
Draft
feat(share): share my streak from the reading streak popup#6358tsahimatsliah wants to merge 2 commits into
tsahimatsliah wants to merge 2 commits into
Conversation
Adds a "Share streak" action to the existing bottom action row of the
reading-streak popup, behind `share_streak` + the sharing-visibility
master gate. Flag off is pixel-identical to the base branch.
- add useShareStreak: short-url + native share, with a separable image
path that feature-detects navigator.canShare({ files }) and degrades
to link + text when files are unsupported or the image is missing
- add ShareStreakButton with streak-length-aware share copy
- render the streak image page (screenshot_wrapper) + StreakShareCard so
the backend screenshot service only has to learn the route
- add share_streak flag, Storybook stories and tests
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Use the milestone target shape (StreaksMilestone/currentStreak) so streak shares union with the celebrations-modal events, and evaluate share_streak only once sharing_visibility passes. 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 (PR 12 / issue #9). Stacked on PR 1 — base branch is
claude/website-sharing-visibility-be6b32, notmain.What changed
Adds a "Share streak" action to the existing bottom action row of the reading-streak popup (
ReadingStreakPopup), next to Settings. The popup renders in three places (header tooltip, sidebar popover, mobile drawer) and all three pick it up from the single insertion point.useShareStreak(packages/shared/src/hooks/streaks/useShareStreak.ts) — short-url resolution viauseGetShortUrl, native share on mobile, clipboard + toast on desktop (useCopyLink). The image path is separable: when animageUrlis supplied andnavigator.canShare({ files })returns true, the native sheet carries the PNG; otherwise it degrades to link + text.canShareis feature-detected (missing implementation, fetch failure, non-ok response and a rejectedshare()all fall through to the link share).ShareStreakButton— icon-only + tooltip on desktop, icon + label on mobile.type="button",aria-label, keyboard-operable. Share copy is streak-length aware (getStreakShareText): plain at <30 days, "the habit stuck" at 30+, "not stopping now" at 100+.StreakShareCard+packages/webapp/pages/image-generator/streak/[userId].tsx— theid="screenshot_wrapper"ISR page, followingimage-generator/devcards/[userId].tsxandbadges/[badgeId].tsxexactly. Data comes from a new publicUSER_STREAK_PROFILE_QUERY(userStreakProfile(id) { current max total }).share_streakflag appended at the end offeatureManagement.ts.Streak data source: the popup already receives the typed
UserStreak(current,max,total,weekStart,lastViewAt) — the share copy usesstreak.current, no invented fields. The share link isuser.permalink(the profile), tagged with the existingReferralCampaignKey.ShareProfile. Logged via the existingLogEvent.ShareLogwithOrigin.ReadingStreak(added in PR 1 — not duplicated) plusprovider,with_imageandstreakinextra.Composition trap avoided: the popup is rendered inside an interactive Tippy tooltip with
onClickOutsidethat closes it. Putting PR 1'sShareActionspopover in here would portal its content outside the tooltip and the outside-click handler would close the popup underneath. So this surface uses the same underlying hooks asShareActions(short-url + native share + copy) with a single-action button instead of a nested popover.Zero streak: the action is hidden when
current === 0— there is nothing to be proud of yet, and hiding it also keeps GrowthBook from evaluating on users who'd never see it (shouldEvaluate).Flag
share_streak, defaultfalse, appended at the very end offeatureManagement.ts. Gated on that flag ANDuseSharingVisibility()(the initiative master kill-switch), both viauseConditionalFeaturewithshouldEvaluate.Flag off is pixel-identical to the base branch: no wrapper element is injected and the Settings button keeps its exact original class string (
w-fullon mobile /ml-autoon desktop). Asserted inReadingStreakPopup.spec.tsx.Image: page shipped, share path deferred on backend
The
screenshot_wrapperpage ships — the frontend half is done and the card renders. What is deferred is the image actually riding along in a share, because two backend pieces are missing:Verification
node ./scripts/typecheck-strict-changed.js— passpnpm --filter shared lint— passpnpm --filter webapp lint— passNODE_ENV=test pnpm --filter shared test— 296 suites / 1994 tests passNODE_ENV=test pnpm --filter webapp test— 44 suites / 297 tests passbuildrun, per instructions.Tests assert: desktop copy → clipboard + toast; mobile →
navigator.sharewith text + link; image attached whencanShare({ files })is true; fallback to link + text whencanSharereturns false and whencanShareis missing entirely; flag-off preserves the current UI (no share control, no injected wrapper, original Settings classes); zero-streak hides the action.Storybook:
Components/Share/ShareStreakButton(short / long / milestone / mobile-with-label / with-image) andComponents/Share/StreakShareCard(the three streak states). Note the repo-wide Storybook GrowthBook mock returns the truthy string'control'for falsy defaults, so a "flag off" story would be misleading — Jest is the real flag-off guarantee here.What I'd A/B
getStreakShareText. Cheap to test, and it isolates whether the "the habit stuck" framing actually reads as bragging-with-taste or as a badge generator.🤖 Generated with Claude Code
Preview domain
https://claude-share-streak.preview.app.daily.dev