Conversation
yujonglee
commented
Dec 13, 2025
- merge notification setting into general setting
- merge account into general
- move out calendar as native tab
- move
- extract ai tab
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughReplaces the prior "settings" tab surface with distinct Changes
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
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. Comment |
✅ Deploy Preview for hyprnote ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for hyprnote-storybook ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
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
handleGoToSettingsnow 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
📒 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, usecn(import from@hypr/utils). It is similar toclsx. Always pass an array and split by logical grouping.
Usemotion/reactinstead offramer-motion.
Files:
apps/desktop/src/components/chat/body/empty.tsxapps/desktop/src/components/main/body/sessions/note-input/enhanced/config-error.tsxapps/desktop/src/components/settings/general/account.tsxapps/desktop/src/components/settings/ai/stt/index.tsxapps/desktop/src/components/settings/ai/stt/select.tsxapps/desktop/src/components/settings/ai/llm/select.tsxapps/desktop/src/components/main/sidebar/profile/auth.tsxapps/desktop/src/components/main/body/calendar/index.tsxapps/desktop/src/components/settings/general/index.tsxapps/desktop/src/components/main/body/ai.tsxapps/desktop/src/components/main/body/sessions/floating/listen.tsxapps/desktop/src/components/main/body/index.tsxapps/desktop/src/store/zustand/tabs/state.tsapps/desktop/src/components/main/sidebar/profile/index.tsxapps/desktop/src/components/main/body/sessions/outer-header/listen.tsxapps/desktop/src/components/main/sidebar/banner/index.tsxapps/desktop/src/components/settings/general/notification.tsxapps/desktop/src/components/main/body/settings.tsxapps/desktop/src/components/main-app-layout.tsxapps/desktop/src/components/settings/ai/llm/index.tsxapps/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.tsapps/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
SettingsAccounttoAccountSettingsaligns 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
SettingsNotificationstoNotificationSettingsViewaligns with the PR's refactoring objectives.
112-138: LGTM!The form state management correctly follows the coding guidelines by using
useFormfrom@tanstack/react-formwith 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 (
AccountSettingsandNotificationSettingsView) 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
headerActionprop 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
headerActionprop 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-betweenproperly positions the title and optionalheaderAction, 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
openAiTabnow accurately describes that it opens the AI tab (not settings), improving code clarity.
45-51: LGTM! Callers updated consistently.Both
handleOpenLLMSettingsandhandleOpenSTTSettingscorrectly use the renamedopenAiTabhelper 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
calendartab and simplifiedsettingstab follow the established pattern for stateless tabs. Clean additions.
127-134: LGTM!The
aitab schema correctly defines nested defaults—the inner default handles missingtabwhen state is provided, and the outer default handles when state itself is omitted. Consistent with other stateful tabs likecontactsandtemplates.
186-193: LGTM!The
TabInputunion 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
calendarandaifollow the singleton tab pattern, correctly treating them as single-instance tabs.