Skip to content

settings migration#2275

Merged
yujonglee merged 6 commits intomainfrom
settings-migration
Dec 13, 2025
Merged

settings migration#2275
yujonglee merged 6 commits intomainfrom
settings-migration

Conversation

@yujonglee
Copy link
Contributor

  • merge notification setting into general setting
  • merge account into general
  • move out calendar as native tab
  • move
  • extract ai tab

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 13, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Replaces the prior "settings" tab surface with distinct ai and calendar tab types, adds AI tab UI with Transcription/Intelligence toggles, removes the old settings tab module, updates tab schema/state/actions, and threads optional headerAction props through AI-related components and consumers.

Changes

Cohort / File(s) Change Summary
Tab schema & state
apps/desktop/src/store/zustand/tabs/schema.ts, apps/desktop/src/store/zustand/tabs/state.ts
Added calendar, ai, and explicit settings tab variants; constrained ai state to `"transcription"
AI tab implementation
apps/desktop/src/components/main/body/ai.tsx
New AI tab: exports TabItemAI, TabContentAI; AIView component adds Transcription/Intelligence toggle, updates AI tab state, and renders STT or LLM with a headerAction.
Calendar tab implementation
apps/desktop/src/components/main/body/calendar/index.tsx
New Calendar tab: exports TabItemCalendar, TabContentCalendar rendering calendar content.
Tab rendering hub
apps/desktop/src/components/main/body/index.tsx
Extended tab item and content routing to handle new ai and calendar tab types, delegating to new components.
Settings tab relocation & removal
apps/desktop/src/components/main/body/settings.tsx, apps/desktop/src/components/main/body/settings/index.tsx
Added a top-level settings.tsx with TabItemSettings/TabContentSettings; removed the old settings/index.tsx module (full deletion of prior settings UI module).
AI component API surface
apps/desktop/src/components/settings/ai/llm/index.tsx, apps/desktop/src/components/settings/ai/llm/select.tsx, apps/desktop/src/components/settings/ai/stt/index.tsx, apps/desktop/src/components/settings/ai/stt/select.tsx
Added optional headerAction prop to LLM, STT, and their SelectProviderAndModel children; UI renders headerAction beside "Model being used" when provided.
Navigation callers updated to ai / calendar
apps/desktop/src/components/chat/body/empty.tsx, apps/desktop/src/components/main-app-layout.tsx, apps/desktop/src/components/main/body/sessions/floating/listen.tsx, apps/desktop/src/components/main/body/sessions/note-input/enhanced/config-error.tsx, apps/desktop/src/components/main/body/sessions/outer-header/listen.tsx, apps/desktop/src/components/main/sidebar/banner/index.tsx, apps/desktop/src/components/main/sidebar/profile/auth.tsx, apps/desktop/src/components/main/sidebar/profile/index.tsx
Replaced openNew(..., type: "settings", state: { tab: ... }) calls with `type: "ai", state: { tab: "transcription"
Settings general UI renames & sections
apps/desktop/src/components/settings/general/account.tsx, apps/desktop/src/components/settings/general/notification.tsx, apps/desktop/src/components/settings/general/index.tsx
Renamed SettingsAccountAccountSettings, SettingsNotificationsNotificationSettingsView; updated import paths and injected Notifications and Account sections into SettingsGeneral.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AIView
    participant TabState
    participant LLM
    participant STT

    User->>AIView: Click "Intelligence" or "Transcription"
    AIView->>TabState: updateAiTabState(tabId, { tab: "intelligence"|"transcription" })
    TabState-->>AIView: updated tab state
    alt ai state = intelligence
        AIView->>LLM: render LLM(headerAction)
        LLM->>User: show LLM UI with headerAction
    else ai state = transcription
        AIView->>STT: render STT(headerAction)
        STT->>User: show STT UI with headerAction
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay special attention to schema/state changes and ensuring all call sites and types are updated to use ai/calendar variants.
  • Verify removal of the old settings module didn't leave unresolved imports or references.
  • Confirm headerAction prop propagation and layout in LLM/STT and their SelectProviderAndModel components.
  • Review navigation normalization in main-app-layout.tsx for correct routing decisions and preserved behavior.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
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.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'settings migration' directly reflects the main purpose of this PR: migrating settings organization by consolidating notification and account settings into general settings, and extracting calendar and AI as native tabs.
Description check ✅ Passed The description lists the key changes being made: merging notification and account settings into general, extracting calendar and AI as separate tabs. While brief, it is clearly related to the changeset.

📜 Recent 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 15e7f6c and 765ef08.

📒 Files selected for processing (1)
  • apps/desktop/src/components/main/sidebar/profile/auth.tsx (2 hunks)

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.

@netlify
Copy link

netlify bot commented Dec 13, 2025

Deploy Preview for hyprnote ready!

Name Link
🔨 Latest commit 765ef08
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/693d4ac71576130008b6bab8
😎 Deploy Preview https://deploy-preview-2275--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 13, 2025

Deploy Preview for hyprnote-storybook ready!

Name Link
🔨 Latest commit 765ef08
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote-storybook/deploys/693d4ac71576130008b6babc
😎 Deploy Preview https://deploy-preview-2275--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.

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 (2)
apps/desktop/src/components/settings/general/account.tsx (1)

183-203: Replace hardcoded delay with proper polling or backend confirmation.

The 3-second setTimeout assumes backend processing time for trial activation. This is brittle and can fail if the backend takes longer or completes faster.

Consider one of these approaches:

Option 1: Poll for status

  const startTrialMutation = useMutation({
    mutationFn: async () => {
      const headers = auth?.getHeaders();
      if (!headers) {
        throw new Error("Not authenticated");
      }
      const client = createClient({ baseUrl: env.VITE_API_URL, headers });
      const { error } = await postBillingStartTrial({
        client,
        query: { interval: "monthly" },
      });
      if (error) {
        throw error;
      }
-
-     await new Promise((resolve) => setTimeout(resolve, 3000));
+     
+     // Poll for trial activation
+     for (let i = 0; i < 10; i++) {
+       await new Promise((resolve) => setTimeout(resolve, 500));
+       await auth?.refreshSession();
+       const { isPro: isProNow } = useBillingAccess();
+       if (isProNow) break;
+     }
    },
    onSuccess: async () => {
-     await auth?.refreshSession();
+     // Already refreshed in polling loop
    },
  });

Option 2: Backend webhook/SSE
Use a webhook or server-sent event to notify when trial activation completes, then refresh session.

apps/desktop/src/components/chat/body/empty.tsx (1)

15-17: Consider renaming for clarity.

The function name handleGoToSettings now opens the AI tab instead of settings. While functional, the name is misleading.

Apply this diff for better clarity:

-  const handleGoToSettings = useCallback(() => {
+  const handleGoToAISettings = useCallback(() => {
     openNew({ type: "ai", state: { tab: "intelligence" } });
   }, [openNew]);

Then update the calls on lines 47 and 89.

📜 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 ad80955 and 15e7f6c.

📒 Files selected for processing (22)
  • apps/desktop/src/components/chat/body/empty.tsx (1 hunks)
  • apps/desktop/src/components/main-app-layout.tsx (1 hunks)
  • apps/desktop/src/components/main/body/ai.tsx (1 hunks)
  • apps/desktop/src/components/main/body/calendar/index.tsx (1 hunks)
  • apps/desktop/src/components/main/body/index.tsx (5 hunks)
  • apps/desktop/src/components/main/body/sessions/floating/listen.tsx (1 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/enhanced/config-error.tsx (1 hunks)
  • apps/desktop/src/components/main/body/sessions/outer-header/listen.tsx (1 hunks)
  • apps/desktop/src/components/main/body/settings.tsx (1 hunks)
  • apps/desktop/src/components/main/body/settings/index.tsx (0 hunks)
  • apps/desktop/src/components/main/sidebar/banner/index.tsx (1 hunks)
  • apps/desktop/src/components/main/sidebar/profile/auth.tsx (1 hunks)
  • apps/desktop/src/components/main/sidebar/profile/index.tsx (1 hunks)
  • apps/desktop/src/components/settings/ai/llm/index.tsx (1 hunks)
  • apps/desktop/src/components/settings/ai/llm/select.tsx (2 hunks)
  • apps/desktop/src/components/settings/ai/stt/index.tsx (1 hunks)
  • apps/desktop/src/components/settings/ai/stt/select.tsx (2 hunks)
  • apps/desktop/src/components/settings/general/account.tsx (1 hunks)
  • apps/desktop/src/components/settings/general/index.tsx (2 hunks)
  • apps/desktop/src/components/settings/general/notification.tsx (1 hunks)
  • apps/desktop/src/store/zustand/tabs/schema.ts (4 hunks)
  • apps/desktop/src/store/zustand/tabs/state.ts (2 hunks)
💤 Files with no reviewable changes (1)
  • apps/desktop/src/components/main/body/settings/index.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{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 instead.
Never do manual state management for form/mutation. Use useForm (from tanstack-form) and useQuery/useMutation (from tanstack-query) instead for 99% of cases. Avoid patterns like setError.
If there are many classNames with conditional logic, use cn (import from @hypr/utils). It is similar to clsx. Always pass an array and split by logical grouping.
Use motion/react instead of framer-motion.

Files:

  • apps/desktop/src/components/chat/body/empty.tsx
  • apps/desktop/src/components/main/body/sessions/note-input/enhanced/config-error.tsx
  • apps/desktop/src/components/settings/general/account.tsx
  • apps/desktop/src/components/settings/ai/stt/index.tsx
  • apps/desktop/src/components/settings/ai/stt/select.tsx
  • apps/desktop/src/components/settings/ai/llm/select.tsx
  • apps/desktop/src/components/main/sidebar/profile/auth.tsx
  • apps/desktop/src/components/main/body/calendar/index.tsx
  • apps/desktop/src/components/settings/general/index.tsx
  • apps/desktop/src/components/main/body/ai.tsx
  • apps/desktop/src/components/main/body/sessions/floating/listen.tsx
  • apps/desktop/src/components/main/body/index.tsx
  • apps/desktop/src/store/zustand/tabs/state.ts
  • apps/desktop/src/components/main/sidebar/profile/index.tsx
  • apps/desktop/src/components/main/body/sessions/outer-header/listen.tsx
  • apps/desktop/src/components/main/sidebar/banner/index.tsx
  • apps/desktop/src/components/settings/general/notification.tsx
  • apps/desktop/src/components/main/body/settings.tsx
  • apps/desktop/src/components/main-app-layout.tsx
  • apps/desktop/src/components/settings/ai/llm/index.tsx
  • apps/desktop/src/store/zustand/tabs/schema.ts
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Agent implementations should use TypeScript and follow the established architectural patterns defined in the agent framework
Agent communication should use defined message protocols and interfaces

Files:

  • apps/desktop/src/store/zustand/tabs/state.ts
  • apps/desktop/src/store/zustand/tabs/schema.ts
🧬 Code graph analysis (8)
apps/desktop/src/components/settings/ai/stt/index.tsx (1)
apps/desktop/src/components/settings/ai/stt/select.tsx (1)
  • SelectProviderAndModel (28-215)
apps/desktop/src/components/settings/ai/stt/select.tsx (1)
apps/desktop/src/components/settings/ai/llm/select.tsx (1)
  • SelectProviderAndModel (32-184)
apps/desktop/src/components/settings/ai/llm/select.tsx (1)
apps/desktop/src/components/settings/ai/stt/select.tsx (1)
  • SelectProviderAndModel (28-215)
apps/desktop/src/components/main/body/calendar/index.tsx (4)
apps/desktop/src/components/main/body/shared.tsx (2)
  • TabItem (32-34)
  • TabItemBase (36-157)
apps/desktop/src/store/zustand/tabs/schema.ts (1)
  • Tab (137-137)
apps/desktop/src/components/main/body/index.tsx (1)
  • StandardTabWrapper (452-471)
apps/desktop/src/components/settings/calendar/index.tsx (1)
  • SettingsCalendar (3-9)
apps/desktop/src/components/settings/general/index.tsx (3)
apps/desktop/src/components/settings/general/notification.tsx (1)
  • NotificationSettingsView (20-429)
apps/desktop/src/components/settings/general/permissions.tsx (1)
  • Permissions (70-111)
apps/desktop/src/components/settings/general/account.tsx (1)
  • AccountSettings (17-159)
apps/desktop/src/components/main/body/ai.tsx (6)
apps/desktop/src/components/main/body/shared.tsx (2)
  • TabItem (32-34)
  • TabItemBase (36-157)
apps/desktop/src/store/zustand/tabs/schema.ts (1)
  • Tab (137-137)
apps/desktop/src/components/main/body/index.tsx (1)
  • StandardTabWrapper (452-471)
packages/utils/src/cn.ts (1)
  • cn (20-22)
apps/desktop/src/components/settings/ai/stt/index.tsx (1)
  • STT (5-13)
apps/desktop/src/components/settings/ai/llm/index.tsx (1)
  • LLM (5-13)
apps/desktop/src/components/main/body/index.tsx (2)
apps/desktop/src/components/main/body/calendar/index.tsx (2)
  • TabItemCalendar (8-28)
  • TabContentCalendar (30-38)
apps/desktop/src/components/main/body/ai.tsx (2)
  • TabItemAI (15-35)
  • TabContentAI (37-43)
apps/desktop/src/store/zustand/tabs/state.ts (2)
apps/desktop/src/store/zustand/tabs/schema.ts (1)
  • Tab (137-137)
apps/desktop/src/store/zustand/tabs/index.ts (1)
  • Tab (19-19)
⏰ 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). (7)
  • GitHub Check: Redirect rules - hyprnote
  • GitHub Check: Header rules - hyprnote
  • GitHub Check: Pages changed - hyprnote
  • GitHub Check: desktop_ci (linux, depot-ubuntu-24.04-8)
  • GitHub Check: desktop_ci (macos, depot-macos-14)
  • GitHub Check: desktop_ci (linux, depot-ubuntu-22.04-8)
  • GitHub Check: fmt
🔇 Additional comments (36)
apps/desktop/src/components/settings/general/account.tsx (2)

11-13: LGTM!

The import path updates are consistent with the directory restructuring.


17-17: LGTM!

The component rename from SettingsAccount to AccountSettings aligns with the PR's refactoring objectives.

apps/desktop/src/components/settings/general/notification.tsx (3)

17-18: LGTM!

The import path updates are consistent with the directory restructuring.


20-20: LGTM!

The component rename from SettingsNotifications to NotificationSettingsView aligns with the PR's refactoring objectives.


112-138: LGTM!

The form state management correctly follows the coding guidelines by using useForm from @tanstack/react-form with proper change listeners and submit handling.

apps/desktop/src/components/settings/general/index.tsx (2)

9-14: LGTM!

The imports correctly reference the renamed components (AccountSettings and NotificationSettingsView) from the restructured modules.


152-162: LGTM!

The composition of notification and account settings into the general settings view aligns well with the PR objectives of merging these sections.

apps/desktop/src/components/settings/ai/llm/index.tsx (1)

5-9: LGTM! Clean prop threading.

The optional headerAction prop is correctly inlined and forwarded to the child component, consistent with the STT implementation pattern.

apps/desktop/src/components/settings/ai/llm/select.tsx (2)

32-34: LGTM! Signature updated correctly.

The optional headerAction prop follows the inline pattern per coding guidelines and matches the STT component implementation.


81-84: LGTM! Header layout matches STT pattern.

The flex container with justify-between properly positions the title and optional headerAction, consistent with the STT implementation shown in relevant snippets.

apps/desktop/src/components/main/sidebar/profile/index.tsx (1)

115-118: LGTM! Calendar promoted to first-class tab.

The navigation change simplifies the API by treating calendar as a native tab type instead of an extension, aligning with the PR objectives.

apps/desktop/src/components/main/body/sessions/note-input/enhanced/config-error.tsx (1)

11-13: LGTM! Consistent navigation update.

The configuration flow now correctly routes to the AI tab with the intelligence subtab, consistent with the broader settings migration.

apps/desktop/src/components/main/body/sessions/outer-header/listen.tsx (1)

176-178: LGTM! Transcription routing correct.

The STT configuration appropriately routes to the AI tab's transcription subtab (versus intelligence for LLM), maintaining the correct functional separation.

apps/desktop/src/components/main/body/sessions/floating/listen.tsx (1)

126-129: LGTM! Consistent with other listen flows.

The action correctly routes to the AI tab's transcription subtab, matching the pattern in outer-header/listen.tsx for STT configuration.

apps/desktop/src/components/main/sidebar/banner/index.tsx (2)

38-43: LGTM! Helper renamed to reflect behavior.

The function name openAiTab now accurately describes that it opens the AI tab (not settings), improving code clarity.


45-51: LGTM! Callers updated consistently.

Both handleOpenLLMSettings and handleOpenSTTSettings correctly use the renamed openAiTab helper with their respective subtabs.

apps/desktop/src/components/main-app-layout.tsx (1)

43-57: LGTM! Settings navigation properly refactored.

The navigation logic correctly routes to the new calendar and AI tabs based on the tab parameter, with appropriate normalization for legacy settings routes.

apps/desktop/src/components/main/body/calendar/index.tsx (2)

8-28: LGTM! Calendar tab item follows established pattern.

The TabItemCalendar implementation is consistent with other tab item components in the codebase.


30-38: LGTM! Calendar tab content properly structured.

The TabContentCalendar wraps the settings calendar view appropriately within the standard tab layout.

apps/desktop/src/components/settings/ai/stt/index.tsx (1)

5-12: LGTM! HeaderAction prop properly threaded through.

The STT component now correctly accepts and forwards the optional headerAction to enable custom header UI.

apps/desktop/src/components/main/body/settings.tsx (2)

8-28: LGTM! Settings tab item follows established pattern.

The TabItemSettings implementation is consistent with other tab item components.


30-42: LGTM! Settings tab content properly structured.

The TabContentSettings correctly renders the general settings view within the standard tab layout.

apps/desktop/src/components/settings/ai/stt/select.tsx (1)

28-30: LGTM! HeaderAction support cleanly integrated.

The SelectProviderAndModel component now accepts and renders an optional headerAction, enabling custom header UI injection.

Also applies to: 77-80

apps/desktop/src/components/main/body/index.tsx (4)

25-26: LGTM! New tab component imports added correctly.

The AI and Calendar tab components are properly imported.


331-342: LGTM! Calendar tab item rendering integrated correctly.

The calendar tab item branch follows the established pattern for tab rendering.


379-390: LGTM! AI tab item rendering integrated correctly.

The AI tab item branch follows the established pattern for tab rendering.


423-425: LGTM! Tab content rendering integrated correctly.

Both calendar and AI tab content branches are properly wired into the rendering logic, with AI correctly receiving the tab prop for state management.

Also applies to: 435-437

apps/desktop/src/components/main/body/ai.tsx (3)

15-35: LGTM! AI tab item follows established pattern.

The TabItemAI implementation is consistent with other tab item components.


37-43: LGTM! AI tab content wrapper properly structured.

The TabContentAI correctly wraps the AI view within the standard tab layout.


45-94: LGTM! AI view implementation is well-structured.

The AIView component correctly manages tab switching between transcription and intelligence modes, with proper state management and conditional rendering.

apps/desktop/src/store/zustand/tabs/state.ts (1)

33-36: LGTM! Tab state updater correctly renamed and refactored.

The updateAiTabState function properly replaces updateSettingsTabState, aligning with the new AI tab type in the refactored architecture.

Also applies to: 55-55

apps/desktop/src/store/zustand/tabs/schema.ts (5)

121-126: LGTM!

The new calendar tab and simplified settings tab follow the established pattern for stateless tabs. Clean additions.


127-134: LGTM!

The ai tab schema correctly defines nested defaults—the inner default handles missing tab when state is provided, and the outer default handles when state itself is omitted. Consistent with other stateful tabs like contacts and templates.


186-193: LGTM!

The TabInput union correctly mirrors the schema definitions with appropriate optional fields.


212-214: LGTM!

New tab types correctly fall through to throw "invalid_resource", consistent with other non-resource tabs.


250-255: LGTM!

The unique IDs for calendar and ai follow the singleton tab pattern, correctly treating them as single-instance tabs.

@yujonglee yujonglee merged commit d954cdb into main Dec 13, 2025
9 of 11 checks passed
@yujonglee yujonglee deleted the settings-migration branch December 13, 2025 11:15
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