Skip to content

New onboarding#2425

Merged
yujonglee merged 2 commits intomainfrom
new-onboarding
Dec 19, 2025
Merged

New onboarding#2425
yujonglee merged 2 commits intomainfrom
new-onboarding

Conversation

@yujonglee
Copy link
Contributor

No description provided.

@netlify
Copy link

netlify bot commented Dec 19, 2025

Deploy Preview for hyprnote ready!

Name Link
🔨 Latest commit 847efe5
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/69452373e1269900087aa1e9
😎 Deploy Preview https://deploy-preview-2425--hyprnote.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Dec 19, 2025

Deploy Preview for hyprnote-storybook ready!

Name Link
🔨 Latest commit 847efe5
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote-storybook/deploys/6945237349568b0008192e3e
😎 Deploy Preview https://deploy-preview-2425--hyprnote-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 19, 2025

📝 Walkthrough

Walkthrough

The PR refactors desktop onboarding navigation from platform-detection-based routing to route-based search parameters. Auth callbacks are wrapped in useCallback and context values in useMemo for performance optimization. Navigation logic consolidates into getNext and getBack functions, with step identifiers exported as constants. The Search type unifies platform, local, and pro flags into a single state object.

Changes

Cohort / File(s) Summary
Auth memoization
apps/desktop/src/auth.tsx
Wrapped setSessionFromTokens, handleAuthCallback, signIn, signOut, and refreshSession in useCallback; wrapped context value in useMemo to stabilize object references and reduce unnecessary re-renders.
Onboarding step components
apps/desktop/src/components/onboarding/calendar.tsx, configure-notice.tsx, login.tsx, permissions.tsx, welcome.tsx
Replaced platform-based navigation with Route.useSearch() to read search parameters; compute next/back steps via getNext(search) and getBack(search); exported STEP_ID_* constants for each step.
Onboarding routing & config
apps/desktop/src/components/onboarding/config.tsx, apps/desktop/src/routes/app/onboarding/index.tsx
Introduced NavigateTarget type and Search type; replaced individual next-step helpers (getNextAfterLogin, getNextAfterConfigureNotice) with unified getNext(ctx) and getBack(ctx) functions; updated STEP_CONFIGS to use STEP_ID_* constants; expanded search validation to include local, pro, and platform fields.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Signature changes: StepProps.onNavigate shifted from accepting a step string to a NavigateTarget context object; verify all call sites are updated correctly.
  • Type propagation: New Search type and its validation schema must propagate consistently through Route.useSearch() calls and navigation handlers across all onboarding components.
  • Memoization dependencies: useCallback and useMemo dependency arrays in auth.tsx require careful verification to ensure no stale closures or missed dependencies.
  • Navigation logic consistency: getNext and getBack functions' switch logic and how they handle step transitions with local/pro/platform flags should be cross-checked against expected navigation flow in each component.

Possibly related PRs

  • Implement Free Trial #2198: Modifies onboarding login and billing-related code (session/entitlement handling), sharing overlapping changes to the same onboarding and authentication files.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 2 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'New onboarding' is vague and generic, using non-descriptive language that doesn't convey specific information about the substantial architectural changes being implemented. Provide a more descriptive title that captures the main architectural change, such as 'Refactor onboarding to use route-based navigation and memoization' or 'Migrate onboarding from platform detection to search-based routing'.
Description check ❓ Inconclusive No description was provided by the author, making it impossible to assess whether the rationale and details of these significant changes are documented. Add a description explaining the key changes: the shift from platform-based to route-based navigation, memoization improvements in auth.tsx, and the new unified search-based context for onboarding steps.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch new-onboarding

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/desktop/src/components/onboarding/config.tsx (1)

17-30: Consider adding exhaustiveness check.

The switch statement covers all current step IDs. However, TypeScript's exhaustiveness checking relies on proper narrowing. Adding an explicit check would catch bugs if a new step is added but not handled here:

🔎 Optional: Add exhaustiveness guard
 export function getNext(ctx: Search): Search["step"] | "done" {
   switch (ctx.step) {
     case STEP_ID_WELCOME:
       if (ctx.local) return STEP_ID_CONFIGURE_NOTICE;
       if (ctx.platform === "macos") return STEP_ID_PERMISSIONS;
       return STEP_ID_LOGIN;
     case STEP_ID_PERMISSIONS:
       return ctx.local ? STEP_ID_CONFIGURE_NOTICE : STEP_ID_LOGIN;
     case STEP_ID_LOGIN:
       return ctx.pro ? "done" : STEP_ID_CONFIGURE_NOTICE;
     case STEP_ID_CONFIGURE_NOTICE:
       return "done";
+    default: {
+      const _exhaustive: never = ctx.step;
+      return _exhaustive;
+    }
   }
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 058b0bd and 847efe5.

📒 Files selected for processing (8)
  • apps/desktop/src/auth.tsx (6 hunks)
  • apps/desktop/src/components/onboarding/calendar.tsx (2 hunks)
  • apps/desktop/src/components/onboarding/config.tsx (1 hunks)
  • apps/desktop/src/components/onboarding/configure-notice.tsx (2 hunks)
  • apps/desktop/src/components/onboarding/login.tsx (3 hunks)
  • apps/desktop/src/components/onboarding/permissions.tsx (4 hunks)
  • apps/desktop/src/components/onboarding/welcome.tsx (3 hunks)
  • apps/desktop/src/routes/app/onboarding/index.tsx (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*

📄 CodeRabbit inference engine (AGENTS.md)

Format using dprint fmt from the root. Do not use cargo fmt.

Files:

  • apps/desktop/src/components/onboarding/configure-notice.tsx
  • apps/desktop/src/components/onboarding/calendar.tsx
  • apps/desktop/src/components/onboarding/permissions.tsx
  • apps/desktop/src/components/onboarding/login.tsx
  • apps/desktop/src/components/onboarding/config.tsx
  • apps/desktop/src/routes/app/onboarding/index.tsx
  • apps/desktop/src/components/onboarding/welcome.tsx
  • apps/desktop/src/auth.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid creating a bunch of types/interfaces if they are not shared. Especially for function props. Just inline them.
Never do manual state management for form/mutation. Use useForm from tanstack-form and useQuery/useMutation from tanstack-query for 99% cases.

Files:

  • apps/desktop/src/components/onboarding/configure-notice.tsx
  • apps/desktop/src/components/onboarding/calendar.tsx
  • apps/desktop/src/components/onboarding/permissions.tsx
  • apps/desktop/src/components/onboarding/login.tsx
  • apps/desktop/src/components/onboarding/config.tsx
  • apps/desktop/src/routes/app/onboarding/index.tsx
  • apps/desktop/src/components/onboarding/welcome.tsx
  • apps/desktop/src/auth.tsx
**/*.{ts,tsx,rs,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

By default, avoid writing comments at all. If you write one, it should be about 'Why', not 'What'.

Files:

  • apps/desktop/src/components/onboarding/configure-notice.tsx
  • apps/desktop/src/components/onboarding/calendar.tsx
  • apps/desktop/src/components/onboarding/permissions.tsx
  • apps/desktop/src/components/onboarding/login.tsx
  • apps/desktop/src/components/onboarding/config.tsx
  • apps/desktop/src/routes/app/onboarding/index.tsx
  • apps/desktop/src/components/onboarding/welcome.tsx
  • apps/desktop/src/auth.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: If there are many classNames with conditional logic, use cn (import from @hypr/utils). Always pass an array and split by logical grouping.
Use motion/react instead of framer-motion.

Files:

  • apps/desktop/src/components/onboarding/configure-notice.tsx
  • apps/desktop/src/components/onboarding/calendar.tsx
  • apps/desktop/src/components/onboarding/permissions.tsx
  • apps/desktop/src/components/onboarding/login.tsx
  • apps/desktop/src/components/onboarding/config.tsx
  • apps/desktop/src/routes/app/onboarding/index.tsx
  • apps/desktop/src/components/onboarding/welcome.tsx
  • apps/desktop/src/auth.tsx
🧬 Code graph analysis (6)
apps/desktop/src/components/onboarding/configure-notice.tsx (2)
apps/desktop/src/components/onboarding/config.tsx (2)
  • getBack (32-44)
  • getNext (17-30)
apps/desktop/src/routes/app/onboarding/index.tsx (1)
  • Route (24-27)
apps/desktop/src/components/onboarding/calendar.tsx (2)
apps/desktop/src/components/onboarding/config.tsx (2)
  • StepProps (13-15)
  • getNext (17-30)
apps/desktop/src/routes/app/onboarding/index.tsx (1)
  • Route (24-27)
apps/desktop/src/components/onboarding/config.tsx (5)
apps/desktop/src/routes/app/onboarding/index.tsx (1)
  • Search (22-22)
apps/desktop/src/components/onboarding/welcome.tsx (1)
  • STEP_ID_WELCOME (9-9)
apps/desktop/src/components/onboarding/configure-notice.tsx (1)
  • STEP_ID_CONFIGURE_NOTICE (5-5)
apps/desktop/src/components/onboarding/permissions.tsx (1)
  • STEP_ID_PERMISSIONS (10-10)
apps/desktop/src/components/onboarding/login.tsx (1)
  • STEP_ID_LOGIN (16-16)
apps/desktop/src/routes/app/onboarding/index.tsx (1)
apps/desktop/src/components/onboarding/config.tsx (3)
  • STEP_IDS (51-56)
  • NavigateTarget (9-11)
  • STEP_CONFIGS (58-63)
apps/desktop/src/components/onboarding/welcome.tsx (3)
apps/desktop/src/components/onboarding/config.tsx (2)
  • StepProps (13-15)
  • getNext (17-30)
apps/desktop/src/routes/app/onboarding/index.tsx (1)
  • Route (24-27)
apps/web/src/routes/auth.tsx (1)
  • Route (17-20)
apps/desktop/src/auth.tsx (2)
apps/desktop/src/utils/index.ts (1)
  • getScheme (8-17)
packages/store/src/schema-external.ts (1)
  • Session (169-169)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Redirect rules - hyprnote
  • GitHub Check: fmt
  • GitHub Check: desktop_ci (macos, depot-macos-14)
  • GitHub Check: desktop_ci (linux, depot-ubuntu-22.04-8)
  • GitHub Check: desktop_ci (linux, depot-ubuntu-24.04-8)
🔇 Additional comments (24)
apps/desktop/src/auth.tsx (7)

108-129: LGTM!

The memoization is correct. Empty dependency array is appropriate since supabase is a module-level constant and React setState functions have stable identities.


131-145: LGTM!

Correct dependency on setSessionFromTokens.


249-253: LGTM!

Empty dependency array is correct as all references (env, getScheme, openUrl) are stable.


255-282: LGTM!

Correct memoization with stable references.


284-298: LGTM!

Correct memoization with stable references.


327-349: LGTM!

Good use of useMemo to stabilize the context value and prevent unnecessary re-renders of consumers. The dependency array correctly includes all dynamic values while supabase is intentionally omitted as a module constant.


14-21: LGTM!

apps/desktop/src/components/onboarding/welcome.tsx (2)

6-9: LGTM!

The imports and constant export align well with the new route-based navigation pattern established across the onboarding flow.


40-53: LGTM!

The navigation logic correctly preserves search state while computing the next step. The "Proceed without account" path properly sets local: true before calling getNext, ensuring the navigation flow respects the local mode configuration.

apps/desktop/src/components/onboarding/configure-notice.tsx (2)

7-16: LGTM!

The back navigation logic correctly handles the conditional case where backStep may be null (e.g., when this is the first step in a local flow). The pattern backStep ? () => onNavigate(...) : undefined ensures onBack is only provided when a back step exists.


30-36: LGTM!

Forward navigation correctly spreads the existing search state and computes the next step dynamically.

apps/desktop/src/components/onboarding/calendar.tsx (1)

53-58: LGTM!

The skip navigation correctly preserves search state and computes the next step.

apps/desktop/src/components/onboarding/permissions.tsx (3)

6-11: LGTM!

The imports and constant export follow the established pattern. The STEP_ID_PERMISSIONS constant is correctly exported for use in the navigation config.


76-102: LGTM!

The navigation setup correctly uses Route.useSearch() to get current state, computes the back step conditionally, and provides onBack only when navigation backward is possible. The pattern is consistent with other onboarding components.


139-152: LGTM!

Forward navigation correctly preserves the search state while computing the next step. The button remains disabled until all permissions are granted, which is appropriate UX.

apps/desktop/src/components/onboarding/login.tsx (3)

10-17: LGTM!

The imports are well-organized and the STEP_ID_LOGIN constant export follows the established pattern.


78-88: LGTM!

The success handler correctly updates the pro flag in the search state before computing the next step, ensuring the navigation logic can make the right decision based on trial status. The error handler provides a reasonable fallback to the configure notice step.


99-113: No changes needed — signIn is already properly memoized.

The signIn function in the auth context is already wrapped in useCallback with an empty dependency array, ensuring it maintains a stable reference and won't cause repeated effect executions. The dependency array in the effect is correctly specified.

Likely an incorrect or invalid review comment.

apps/desktop/src/routes/app/onboarding/index.tsx (3)

40-50: LGTM!

The navigation callback correctly destructures the NavigateTarget, handles the "done" case, and preserves the remaining search parameters during navigation. The dependency array is correct.


52-67: LGTM!

The step lookup gracefully handles unknown steps by returning null, and the component rendering pattern is clean.


15-20: platform() is safely synchronous.

The platform() function returns a string describing the operating system, with the value set at compile time. This makes it a synchronous function that can be safely invoked at module load time. No lazy evaluation or deferred initialization is needed, as the value is determined at compile time, not at runtime.

apps/desktop/src/components/onboarding/config.tsx (3)

3-11: LGTM!

The NavigateTarget type cleanly extends Search to include "done" as a valid step target, enabling type-safe navigation including flow completion.


32-44: LGTM!

The back navigation logic correctly mirrors the forward flow, properly accounting for platform and local mode variations.


51-63: LGTM!

The STEP_IDS array with as const ensures proper tuple typing for zod's z.enum(), and STEP_CONFIGS correctly maps each step ID to its component.

@yujonglee yujonglee merged commit 4885168 into main Dec 19, 2025
16 checks passed
@yujonglee yujonglee deleted the new-onboarding branch December 19, 2025 12:47
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