Skip to content

Invite OK Desktop users to subscribe to product updates from the…#418

Merged
inkeep-oss-sync[bot] merged 1 commit into
mainfrom
copybara/sync
Jul 1, 2026
Merged

Invite OK Desktop users to subscribe to product updates from the…#418
inkeep-oss-sync[bot] merged 1 commit into
mainfrom
copybara/sync

Conversation

@inkeep-oss-sync

Copy link
Copy Markdown
Contributor

Invite OK Desktop users to subscribe to product updates from the post-update release-notes card. When the app updates, the "Updated to Version X · Release notes" card in the sidebar footer now also carries a compact "Stay in the loop" subscribe form (reusing the existing form) with a "Follow us on" row for X, GitHub, and Discord — shown only when the user hasn't already subscribed or dismissed it, and for at most three distinct update versions. It never appears on its own (no update, no prompt) and won't re-nag on reopen. Dismissing closes the whole card and stops the prompt for good; subscribing from here or the Resources menu retires it. All state is device-local; web and CLI are unaffected.

… (#2324)

* feat(open-knowledge): subscribe card for returning users (OK Desktop)

Add a "Stay in the loop" subscribe card to the OK Desktop sidebar footer,
shown to returning users who haven't subscribed to product updates yet.

- Reuses the existing SubscribeForm (compact arrow submit for the narrow
  footer) plus a "Follow us on" row linking X, GitHub, and Discord.
- Visibility: desktop-only, mutually exclusive with the first-run
  onboarding card ("not first time" = onboarding not showing), gated on a
  confirmed returning-user probe, capped at 3 total appearances.
- Device-local store mirrors the onboarding-card store; subscribing from
  this card OR the Resources popover retires it permanently, as does
  dismissal. Web/CLI render nothing.
- Extracts shared social URLs into lib/social-links.ts.

* fix(open-knowledge): drop stale knip ignore for @hookform/resolvers

The subscribe card makes SubscribeForm (which uses zodResolver from
@hookform/resolvers/zod) reachable from a mounted component, so knip now
detects @hookform/resolvers as genuinely used — the "uninstantiated"
ignoreDependencies entry is stale and knip fails the lint job on it.

Remove the entry and add a direct unit test for evaluateReturningUser
(mirrors the onboarding hook's evaluateFreshProject test) so the exported
fail-safe is covered rather than flagged as an unused export.

* fix(open-knowledge): a11y review fixes + valid doc shape in subscribe-card DOM test

- SubscribeCard: give the <section> a named region landmark (aria-label
  "Stay in the loop") — the heading is a <p> from SubscribeForm, so
  aria-labelledby has no target (claude review).
- SubscribeForm: drop the redundant aria-label on the compact submit button;
  the sr-only "Subscribe" span already supplies the accessible name (claude
  review).
- use-subscribe-card-visible.dom.test: the "existing content" case mocked a
  document with the wrong shape (name/path instead of docName/size/modified),
  so DocumentListSuccessSchema.safeParse threw and the fail-safe returned
  false — the test timed out waiting for the card. Use a schema-valid doc.

* refactor(open-knowledge): a11y nav grouping + onboarding-suppressed visibility tests

Address non-blocking review suggestions on the subscribe card:
- Group the "Follow us on" social links in a labeled <nav> so screen-reader
  users get a named navigation region instead of loose links.
- Cover the onboarding dismissed/completed → card visible branches in the
  visibility hook's DOM tests (previously only the "occupying → hidden"
  positive case was tested).

* feat(open-knowledge): combine subscribe prompt into the post-update release-notes card

Replace the always-on standalone subscribe card with a subscribe prompt that
rides along with the post-update what's-new notice. Rationale: an always-visible
card nags on every launch and the two cards forced two dismissals; tying the
ask to the (infrequent) release-notes moment is contextual and self-limiting.

- When a what's-new notice fires and the subscribe prompt is eligible, the
  footer renders the COMBINED card: the "Stay in the loop" form + socials on
  top, an "Updated to Version X · Release notes" footer row below. Otherwise the
  plain what's-new notice shows, unchanged (its 60s auto-dismiss, cross-window
  dismiss, and priority behavior are untouched).
- No standalone card: if no update, no prompt. Removed SubscribeCardMount, the
  returning-user probe (use-subscribe-card-visible), and its tests — a what's-new
  event already implies a returning user.
- No re-nag on reopen: the combined card uses a distinct notice id and marks the
  version seen in main at creation (so the dismiss echo can't remove it, and a
  reopen won't re-fire it); the shown version is persisted device-local. Prompt
  is capped at 3 distinct versions, and never after subscribe/dismiss.
- Lifecycle: combined card has no auto-dismiss (stays until acted). Dismiss (✕)
  closes the card and stops the prompt for good. On subscribe, it shows the
  confirmation, collapses the social row, and auto-dismisses after 60s.
- Store reworked to {subscribed, dismissed, shownVersions}; adds
  isSubscribeCombinedEligible. SubscribeForm gains compactSubmit (arrow submit).

* test(open-knowledge): cover the combined-subscribe path in attachUpdateSubscribers

Address the review's blocking finding: the combined branch (the core of the
redesign) had no subscription-layer coverage. Add 3 tests to UpdateNotices.test:
- eligible → combined notice (distinct `whats-new-combined-<version>` id,
  combinedSubscribe + whatsNew data, onShown + dismissWhatsNew at creation, no
  auto-dismiss timer)
- ineligible → plain notice with auto-dismiss, onShown not called
- onWhatsNewDismissed echo does NOT remove the combined card (the distinct-id
  invariant that keeps a cross-window dismiss from killing it mid-session)

Also refresh the stale subscribe-store boot comment in main.tsx (show-count →
shown-versions; drop the "returning-user nudge" wording from the old design).

---------

GitOrigin-RevId: f98fed2d8f5679376ac79047968e38787b391e76

@inkeep-internal-ci inkeep-internal-ci Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated approval from agents-private public-mirror-sync (run: https://github.com/inkeep/agents-private/actions/runs/28532415882). Source of truth is the monorepo; direct edits on inkeep/open-knowledge are overwritten on next sync.

@inkeep-oss-sync
inkeep-oss-sync Bot merged commit 4b56235 into main Jul 1, 2026
@inkeep-oss-sync
inkeep-oss-sync Bot deleted the copybara/sync branch July 1, 2026 16:33
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