Skip to content

license key activation#1192

Closed
yujonglee wants to merge 11 commits intomainfrom
membership-keygen
Closed

license key activation#1192
yujonglee wants to merge 11 commits intomainfrom
membership-keygen

Conversation

@yujonglee
Copy link
Contributor

No description provided.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 22, 2025

📝 Walkthrough

Walkthrough

This change removes the legacy /app/plans route and all related pricing plan UI, replacing it with a new license and billing management system. It introduces new hooks and components for handling license activation, subscription, and billing portal access, updates navigation event handling to use structured objects, and modifies window and tray plugin APIs accordingly. Several UI components and settings tabs are refactored or replaced, and new dependencies are added to support the license and billing features.

Changes

Files / Areas Summary
apps/desktop/package.json, apps/desktop/src-tauri/Cargo.toml, plugins/windows/Cargo.toml, plugins/tray/Cargo.toml Added dependencies for keygen plugins and serde_json; updated dependency order.
apps/desktop/src-tauri/capabilities/default.json Added new permission "keygen:default".
apps/desktop/src-tauri/src/lib.rs Integrated tauri_plugin_keygen plugin initialization.
apps/desktop/src-tauri/src/deeplink.rs Added /license deeplink support and related parsing logic.
apps/desktop/src/hooks/use-license.ts, apps/desktop/src/hooks/use-billing.ts Introduced new React hooks for license and billing management.
apps/desktop/src/components/license.tsx Added LicenseRefreshProvider for periodic license refresh.
apps/desktop/src/components/settings/components/tab-icon.tsx, .../types.ts Replaced "lab" tab with "billing" tab; updated icons and tab types.
apps/desktop/src/components/settings/views/billing.tsx Refactored billing UI: removed pricing plans, added license/subscription management interface.
apps/desktop/src/components/left-sidebar/top-area/settings-button.tsx Updated to show billing tab, added DropdownHeader for plan status, used license hook.
apps/desktop/src/components/toolbar/index.tsx, apps/desktop/src/routeTree.gen.ts Removed /app/plans toolbar and route references.
apps/desktop/src/routes/app.plans.tsx Deleted the entire /app/plans route and pricing card components.
apps/desktop/src/routes/app.settings.tsx Added conditional rendering for new billing tab.
apps/desktop/src/routes/app.tsx Wrapped app in LicenseRefreshProvider.
apps/desktop/src/components/human-profile/past-notes.tsx, .../toast/model-select.tsx, .../chat/empty-chat-state.tsx Updated window navigation to use structured event objects instead of string paths.
apps/desktop/src/routes/__root.tsx Updated navigation event handling, disabled a scan call, added TS ignore.
plugins/windows/js/bindings.gen.ts Changed navigation event parameter to object with path and search.
plugins/windows/src/ext.rs, plugins/windows/src/commands.rs, plugins/windows/src/events.rs Removed Plans window, updated navigation event handling to use structured objects, added search field.
plugins/tray/src/ext.rs Updated tray menu navigation to use structured navigation objects.
apps/desktop/src/locales/en/messages.po, apps/desktop/src/locales/ko/messages.po Updated translation metadata and marked obsolete entries.
packages/ui/src/hooks/use-mobile.tsx Refactored React import style, no logic changes.
scripts/s3/upload.sh Updated S3 upload configuration (credentials, endpoint, bucket).

Sequence Diagram(s)

sequenceDiagram
    participant UI as User Interface
    participant LicenseHook as useLicense
    participant KeygenAPI as tauri-plugin-keygen-api
    participant BillingHook as useBilling
    participant Backend as Billing Server

    UI->>LicenseHook: Query current license
    LicenseHook->>KeygenAPI: getLicense()
    KeygenAPI-->>LicenseHook: License data
    LicenseHook-->>UI: License status

    UI->>LicenseHook: Activate license (with key)
    LicenseHook->>KeygenAPI: activateLicense(key)
    KeygenAPI-->>LicenseHook: Activation result
    LicenseHook-->>UI: Updated license status

    UI->>BillingHook: Checkout (email, interval)
    BillingHook->>Backend: POST /checkout
    Backend-->>BillingHook: Checkout URL
    BillingHook-->>UI: Open checkout URL

    UI->>BillingHook: Open billing portal
    BillingHook->>Backend: POST /portal
    Backend-->>BillingHook: Portal URL
    BillingHook-->>UI: Open portal URL
Loading
sequenceDiagram
    participant UI as User Interface
    participant WindowPlugin as plugins/windows
    participant App as Tauri App

    UI->>WindowPlugin: windowEmitNavigate({path, search})
    WindowPlugin->>App: Emit navigation event with path and search
    App-->>WindowPlugin: Navigation handled
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c1e0c3f and 06d7963.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (8)
  • apps/desktop/src-tauri/Cargo.toml (1 hunks)
  • apps/desktop/src/components/toolbar/index.tsx (1 hunks)
  • apps/desktop/src/locales/en/messages.po (25 hunks)
  • apps/desktop/src/locales/ko/messages.po (25 hunks)
  • apps/desktop/src/routeTree.gen.ts (0 hunks)
  • apps/desktop/src/routes/app.settings.tsx (2 hunks)
  • plugins/windows/js/bindings.gen.ts (2 hunks)
  • plugins/windows/src/ext.rs (3 hunks)
💤 Files with no reviewable changes (1)
  • apps/desktop/src/routeTree.gen.ts
✅ Files skipped from review due to trivial changes (3)
  • apps/desktop/src-tauri/Cargo.toml
  • apps/desktop/src/locales/en/messages.po
  • apps/desktop/src/locales/ko/messages.po
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/desktop/src/routes/app.settings.tsx
  • plugins/windows/js/bindings.gen.ts
  • apps/desktop/src/components/toolbar/index.tsx
  • plugins/windows/src/ext.rs
⏰ 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). (1)
  • GitHub Check: ci (windows, windows-latest)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch membership-keygen

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 4

🧹 Nitpick comments (2)
packages/ui/src/hooks/use-mobile.tsx (1)

1-17: SSR-safe guard for DOM access

window is only referenced in useEffect, but when this hook is imported in an SSR context the component will still execute the top-level function, so any future refactors could accidentally introduce a hard crash. A tiny guard keeps you future-proof without violating the “no error-handling” rule.

 export function useIsMobile() {
-  const [isMobile, setIsMobile] = useState<boolean | undefined>(undefined);
+  // undefined until we confirm a browser environment
+  const [isMobile, setIsMobile] = useState<boolean | undefined>(undefined);
 
   useEffect(() => {
+    if (typeof window === "undefined") return; // SSR
     const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
scripts/s3/upload.sh (1)

1-6: Clean up commented code.

Consider removing the commented-out configuration lines since they're no longer needed and add visual clutter.

-# CREDENTIALS_FILE="$HOME/hyprnote-r2.toml"
 CREDENTIALS_FILE="$HOME/hyprnote-tigris.toml"
-# ENDPOINT_URL="https://3db5267cdeb5f79263ede3ec58090fe0.r2.cloudflarestorage.com"
 ENDPOINT_URL="https://hyprnote-models.t3.storage.dev/hypo-llm/?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=tid_jMCCPSPwjkhTVegMJMCLU_uamBoBNYeuKYZVnoCiWlVvyDTkRX%2F20250721%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20250721T235903Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=aa0f515992dd70d1ab5a270543b7947020ff9726c8ee5314910c1b9acafc7066"
-# BUCKET="hyprnote-cache"
 BUCKET="hyprnote-models"
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0b21411 and b1d80bd.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • apps/desktop/package.json (1 hunks)
  • apps/desktop/src-tauri/Cargo.toml (1 hunks)
  • apps/desktop/src-tauri/capabilities/default.json (1 hunks)
  • apps/desktop/src-tauri/src/lib.rs (1 hunks)
  • apps/desktop/src/hooks/use-license.ts (1 hunks)
  • packages/ui/src/hooks/use-mobile.tsx (1 hunks)
  • scripts/s3/upload.sh (1 hunks)
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}

⚙️ CodeRabbit Configuration File

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

Files:

  • apps/desktop/src-tauri/src/lib.rs
  • packages/ui/src/hooks/use-mobile.tsx
  • apps/desktop/src/hooks/use-license.ts
🪛 Shellcheck (0.10.0)
scripts/s3/upload.sh

[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.

(SC2148)

🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}

⚙️ CodeRabbit Configuration File

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

Files:

  • apps/desktop/src-tauri/src/lib.rs
  • packages/ui/src/hooks/use-mobile.tsx
  • apps/desktop/src/hooks/use-license.ts
🪛 Shellcheck (0.10.0)
scripts/s3/upload.sh

[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.

(SC2148)

🔇 Additional comments (4)
apps/desktop/package.json (1)

96-97: Freeze key-gen API versions for stability

Both new deps point to moving targets (github:#v2 and ^0.2.3). Consider pinning to an exact commit/tag (as with Cargo) to avoid silent API breaks that could desync frontend ↔ backend license logic.

apps/desktop/src-tauri/capabilities/default.json (1)

91-93: LGTM – new permissions registered

dialog:allow-save and keygen:default fit the existing pattern and don’t duplicate earlier entries.

apps/desktop/src/hooks/use-license.ts (2)

5-46: LGTM! Well-structured license management hook.

The implementation correctly integrates the Tauri keygen plugin with React Query for license state management. The automatic refetching and mutation success callbacks ensure proper state synchronization.


20-25: Confirm empty entitlements array is intentional

The call to validateCheckoutKey in apps/desktop/src/hooks/use-license.ts passes an empty entitlements array, and no other usages of entitlements were found in the codebase. Please verify this aligns with your licensing model. If specific entitlements should be enforced, update this call accordingly; otherwise, consider adding a comment to explain why an empty array is correct here.

• File: apps/desktop/src/hooks/use-license.ts, lines 20–25

await keygen.validateCheckoutKey({
  key,
  entitlements: [],        // <- confirm this is intentional
  ttlSeconds: 60 * 60 * 24 * 7, // 7 days
  ttlForever: false,
});

Comment on lines +102 to +108
.plugin(
tauri_plugin_keygen::Builder::new(
"76dfe152-397c-4689-9c5e-3669cefa34b9",
"13f18c98b8c1e5539d92df4aad2d51f4d203d5aead296215df7c3d6376b78b13",
)
.build(),
)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Move product & hash out of source to env/CFG

Hard-coding the product UUID and checksum exposes them to the public repo history and requires a new build for every value change. Reading them from tauri.conf.json or env variables keeps secrets out of VCS and lets you rotate keys without shipping a new binary.

-        .plugin(
-            tauri_plugin_keygen::Builder::new(
-                "76dfe152-397c-4689-9c5e-3669cefa34b9",
-                "13f18c98b8c1e5539d92df4aad2d51f4d203d5aead296215df7c3d6376b78b13",
-            )
-            .build(),
-        )
+        .plugin(
+            tauri_plugin_keygen::Builder::new(
+                env!("KEYGEN_PRODUCT_ID"),
+                env!("KEYGEN_HASH"),
+            )
+            .build(),
+        )

(Adjust to your preferred config mechanism.)

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.plugin(
tauri_plugin_keygen::Builder::new(
"76dfe152-397c-4689-9c5e-3669cefa34b9",
"13f18c98b8c1e5539d92df4aad2d51f4d203d5aead296215df7c3d6376b78b13",
)
.build(),
)
.plugin(
tauri_plugin_keygen::Builder::new(
env!("KEYGEN_PRODUCT_ID"),
env!("KEYGEN_HASH"),
)
.build(),
)
🤖 Prompt for AI Agents
In apps/desktop/src-tauri/src/lib.rs around lines 102 to 108, the product UUID
and hash are hard-coded, exposing secrets in the source code and requiring
rebuilds for changes. Refactor the code to read these values from environment
variables or the tauri.conf.json configuration file instead. This will keep
secrets out of version control and allow key rotation without rebuilding the
binary. Adjust the code to load and pass these values dynamically to the
tauri_plugin_keygen::Builder.

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: 2

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b1d80bd and edf23b6.

📒 Files selected for processing (9)
  • apps/desktop/src-tauri/src/deeplink.rs (4 hunks)
  • apps/desktop/src/components/license.tsx (1 hunks)
  • apps/desktop/src/components/settings/components/tab-icon.tsx (2 hunks)
  • apps/desktop/src/components/settings/components/types.ts (3 hunks)
  • apps/desktop/src/components/settings/views/billing.tsx (1 hunks)
  • apps/desktop/src/hooks/use-billing.ts (1 hunks)
  • apps/desktop/src/hooks/use-license.ts (1 hunks)
  • apps/desktop/src/routes/app.settings.tsx (3 hunks)
  • apps/desktop/src/routes/app.tsx (3 hunks)
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}

⚙️ CodeRabbit Configuration File

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

Files:

  • apps/desktop/src/hooks/use-license.ts
  • apps/desktop/src/components/settings/components/types.ts
  • apps/desktop/src/routes/app.settings.tsx
  • apps/desktop/src/components/settings/components/tab-icon.tsx
  • apps/desktop/src/hooks/use-billing.ts
  • apps/desktop/src/components/license.tsx
  • apps/desktop/src/components/settings/views/billing.tsx
  • apps/desktop/src-tauri/src/deeplink.rs
✅ Files skipped from review due to trivial changes (1)
  • apps/desktop/src/routes/app.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}

⚙️ CodeRabbit Configuration File

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

Files:

  • apps/desktop/src/hooks/use-license.ts
  • apps/desktop/src/components/settings/components/types.ts
  • apps/desktop/src/routes/app.settings.tsx
  • apps/desktop/src/components/settings/components/tab-icon.tsx
  • apps/desktop/src/hooks/use-billing.ts
  • apps/desktop/src/components/license.tsx
  • apps/desktop/src/components/settings/views/billing.tsx
  • apps/desktop/src-tauri/src/deeplink.rs
⏰ 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). (2)
  • GitHub Check: ci (macos, macos-latest)
  • GitHub Check: ci (windows, windows-latest)
🔇 Additional comments (32)
apps/desktop/src/components/settings/components/tab-icon.tsx (2)

6-6: LGTM: Clean import update

The import correctly adds CreditCardIcon for the new billing tab functionality.


33-34: LGTM: Proper case addition

The new billing case correctly returns the CreditCardIcon with consistent styling.

apps/desktop/src/routes/app.settings.tsx (3)

10-10: LGTM: Correct import addition

The Billing component import is properly added to support the new billing tab.


126-127: LGTM: Consistent translation pattern

The billing tab label follows the same conditional translation pattern as other tabs.


161-161: LGTM: Proper content rendering

The billing content rendering maintains consistency with other tab implementations.

apps/desktop/src/components/settings/components/types.ts (3)

2-12: LGTM: Import statement properly updated

All necessary icons are correctly imported for the tab configuration changes.


22-23: LGTM: Tab type correctly updated

The type definition properly reflects the removal of "lab" and addition of "billing" tabs.


32-34: Verify icon assignments align with user expectations

The icon assignments have been changed: integrations now uses MessageSquare, feedback uses BlocksIcon, and billing uses CreditCard. Ensure these icon choices align with the intended user experience for each tab's functionality.

apps/desktop/src/hooks/use-billing.ts (3)

3-5: LGTM: Environment-based server configuration

The server URL selection correctly switches between development and production environments.


14-26: LGTM: Well-configured query setup

The query configuration with 30-second refetch intervals and window focus refetching is appropriate for billing data that may change frequently.


28-34: LGTM: Clean portal function implementation

The portal function correctly returns a typed Promise and uses appropriate HTTP method and headers.

apps/desktop/src/components/license.tsx (4)

8-11: LGTM: Proper loading state handling

The early return for loading state prevents unnecessary operations during license data fetch.


13-17: LGTM: Correct refresh logic

The function properly checks both conditions (should refresh and not pending) before triggering a license refresh.


19-22: LGTM: Proper interval management

The immediate execution and 10-minute interval setup with cleanup on unmount follows React best practices.


23-23: LGTM: Comprehensive dependency array

All dependencies are correctly included in the useEffect dependency array.

apps/desktop/src/hooks/use-license.ts (7)

1-5: LGTM! Clean imports and proper query key definition.

The imports are appropriate and the LICENSE_QUERY_KEY constant follows React Query best practices with the as const assertion.


10-20: License query implementation looks solid.

The query correctly validates the license and handles the invalid case by returning null. The 5-minute refetch interval ensures license status stays current.


22-41: Refresh license mutation is well-implemented.

The flow correctly retrieves the cached key, validates it with appropriate TTL, and updates the query cache. Error handling follows the established patterns.


43-58: shouldRefresh logic is sound and well-implemented.

The function correctly identifies when a license needs refreshing (within 3 days of expiry) and handles edge cases appropriately. The date calculation logic is accurate.


60-73: License activation mutation follows consistent patterns.

The implementation correctly validates the provided key and updates the cache on success. The TTL configuration matches other mutations for consistency.


75-86: Deactivation logic is correct and efficient.

Using Promise.all for parallel reset operations is appropriate, and clearing the query cache on success properly reflects the deactivated state.


88-95: Well-structured hook interface.

The return object provides a clean, comprehensive API for license management operations. The hook follows React conventions and patterns effectively.

apps/desktop/src-tauri/src/deeplink.rs (3)

27-33: Clean deeplink routing addition.

The new license path follows the established pattern perfectly, and the added comments provide helpful context about the origin of each deeplink path.


87-108: License query parser follows established patterns.

The function structure and error handling are consistent with existing parsers. The dual destination approach (main window + settings window) matches the registration flow appropriately.


121-124: Simple and appropriate struct definition.

The LicenseQuery struct follows the established pattern with serde derives and uses a clear field name that matches the expected URL parameter.

apps/desktop/src/components/settings/views/billing.tsx (7)

1-9: Clean and necessary imports.

All imported components and icons are utilized in the component. The import structure is well-organized.


25-43: Well-designed component interface.

The props interface is comprehensive and appropriately typed, covering all necessary billing scenarios with good default values and optional parameters.


44-46: Appropriate local state management.

The useState hooks properly manage form inputs with sensible defaults. The yearly default aligns with the discount messaging in the UI.


49-77: Well-structured header section.

The conditional rendering for Pro vs Free plans is clean, and the billing portal integration provides good user experience for subscription management.


78-102: Secure and user-friendly Pro plan interface.

The masked license key display and clear deactivation messaging provide good security and user experience. The destructive button styling appropriately signals the action's impact.


105-178: Well-designed subscription interface.

The tabbed approach, form validation, and clear billing options create a smooth subscription flow. The external documentation link helps users make informed decisions.


179-197: Clean license activation interface.

The simple input and validation pattern works well for license key entry. The monospace font helps with key readability and the disabled state provides good feedback.

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

♻️ Duplicate comments (1)
apps/desktop/src/components/settings/views/billing.tsx (1)

13-26: Good integration with license hook.

The component properly integrates with the useLicense hook and conditionally renders based on license validity. The structure is clean and follows React best practices.

🧹 Nitpick comments (1)
apps/desktop/src/components/left-sidebar/top-area/settings-button.tsx (1)

44-47: Function name is misleading.

The function handleClickPlans now opens the settings window instead of plans. Consider renaming it to handleClickBilling or similar to reflect its actual behavior.

-  const handleClickPlans = () => {
+  const handleClickBilling = () => {
     setOpen(false);
     windowsCommands.windowShow({ type: "settings" });
   };
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between edf23b6 and c80a088.

📒 Files selected for processing (7)
  • apps/desktop/src/components/left-sidebar/top-area/settings-button.tsx (5 hunks)
  • apps/desktop/src/components/settings/views/billing.tsx (1 hunks)
  • apps/desktop/src/components/toolbar/index.tsx (1 hunks)
  • apps/desktop/src/routeTree.gen.ts (0 hunks)
  • apps/desktop/src/routes/app.plans.tsx (0 hunks)
  • plugins/windows/js/bindings.gen.ts (1 hunks)
  • plugins/windows/src/ext.rs (0 hunks)
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}

⚙️ CodeRabbit Configuration File

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

Files:

  • plugins/windows/js/bindings.gen.ts
  • apps/desktop/src/components/toolbar/index.tsx
  • apps/desktop/src/components/left-sidebar/top-area/settings-button.tsx
  • apps/desktop/src/components/settings/views/billing.tsx
💤 Files with no reviewable changes (3)
  • plugins/windows/src/ext.rs
  • apps/desktop/src/routeTree.gen.ts
  • apps/desktop/src/routes/app.plans.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}

⚙️ CodeRabbit Configuration File

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

Files:

  • plugins/windows/js/bindings.gen.ts
  • apps/desktop/src/components/toolbar/index.tsx
  • apps/desktop/src/components/left-sidebar/top-area/settings-button.tsx
  • apps/desktop/src/components/settings/views/billing.tsx
🔇 Additional comments (6)
plugins/windows/js/bindings.gen.ts (1)

73-73: LGTM - Type union correctly updated.

The removal of the "plans" variant from the HyprWindow type union is consistent with the elimination of plans functionality across the codebase.

apps/desktop/src/components/toolbar/index.tsx (1)

5-5: Import cleanup looks good.

The removal of unused imports aligns with the coding guidelines and the elimination of plans functionality.

apps/desktop/src/components/left-sidebar/top-area/settings-button.tsx (1)

110-142: Well-structured reusable component.

The DropdownHeader component is well-implemented with proper conditional rendering and styling based on the isPro state.

apps/desktop/src/components/settings/views/billing.tsx (3)

28-140: Well-structured FreeSection component.

The tabbed interface for subscription vs license activation is intuitive and the form validation (disabled buttons when inputs are empty) provides good UX.


142-195: ProSection implementation looks solid.

The license key masking and deactivation functionality are well-implemented. The TODO comments are acceptable for the current development stage.


197-226: Excellent reusable SectionContainer component.

The component provides consistent layout and styling with proper prop typing and conditional rendering.

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: 5

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c80a088 and d9427f0.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (18)
  • apps/desktop/src-tauri/src/deeplink.rs (4 hunks)
  • apps/desktop/src/components/human-profile/past-notes.tsx (1 hunks)
  • apps/desktop/src/components/left-sidebar/top-area/settings-button.tsx (5 hunks)
  • apps/desktop/src/components/license.tsx (1 hunks)
  • apps/desktop/src/components/right-panel/components/chat/empty-chat-state.tsx (2 hunks)
  • apps/desktop/src/components/settings/views/billing.tsx (1 hunks)
  • apps/desktop/src/components/toast/model-select.tsx (3 hunks)
  • apps/desktop/src/hooks/use-billing.ts (1 hunks)
  • apps/desktop/src/hooks/use-license.ts (1 hunks)
  • apps/desktop/src/routes/__root.tsx (3 hunks)
  • packages/utils/src/navigation.ts (1 hunks)
  • plugins/tray/Cargo.toml (1 hunks)
  • plugins/tray/src/ext.rs (2 hunks)
  • plugins/windows/Cargo.toml (1 hunks)
  • plugins/windows/js/bindings.gen.ts (2 hunks)
  • plugins/windows/src/commands.rs (2 hunks)
  • plugins/windows/src/events.rs (1 hunks)
  • plugins/windows/src/ext.rs (3 hunks)
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}

⚙️ CodeRabbit Configuration File

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

Files:

  • apps/desktop/src/components/human-profile/past-notes.tsx
  • packages/utils/src/navigation.ts
  • plugins/windows/src/events.rs
  • apps/desktop/src/components/right-panel/components/chat/empty-chat-state.tsx
  • apps/desktop/src/components/toast/model-select.tsx
  • plugins/tray/src/ext.rs
  • apps/desktop/src/routes/__root.tsx
  • plugins/windows/src/commands.rs
  • apps/desktop/src/hooks/use-billing.ts
✅ Files skipped from review due to trivial changes (2)
  • plugins/tray/Cargo.toml
  • plugins/windows/Cargo.toml
🚧 Files skipped from review as they are similar to previous changes (7)
  • apps/desktop/src/hooks/use-license.ts
  • apps/desktop/src/components/left-sidebar/top-area/settings-button.tsx
  • apps/desktop/src-tauri/src/deeplink.rs
  • apps/desktop/src/components/license.tsx
  • plugins/windows/js/bindings.gen.ts
  • apps/desktop/src/components/settings/views/billing.tsx
  • plugins/windows/src/ext.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}

⚙️ CodeRabbit Configuration File

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

Files:

  • apps/desktop/src/components/human-profile/past-notes.tsx
  • packages/utils/src/navigation.ts
  • plugins/windows/src/events.rs
  • apps/desktop/src/components/right-panel/components/chat/empty-chat-state.tsx
  • apps/desktop/src/components/toast/model-select.tsx
  • plugins/tray/src/ext.rs
  • apps/desktop/src/routes/__root.tsx
  • plugins/windows/src/commands.rs
  • apps/desktop/src/hooks/use-billing.ts
⏰ 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). (2)
  • GitHub Check: ci (windows, windows-latest)
  • GitHub Check: ci (macos, macos-latest)
🔇 Additional comments (12)
apps/desktop/src/components/human-profile/past-notes.tsx (1)

46-46: LGTM: Navigation event structure updated correctly.

The change properly updates the navigation call to use the new structured format with explicit path and search properties, maintaining backward compatibility while aligning with the standardized navigation event handling.

plugins/windows/src/events.rs (2)

55-57: LGTM: Added deserialization support to event structures.

Adding serde::Deserialize to the common event derives is appropriate for bidirectional event communication and maintains consistency with the existing serialization capability.


65-65: LGTM: Enhanced Navigate struct with search parameters.

The addition of the optional search field properly supports structured navigation with query parameters while maintaining backward compatibility through the Option type.

apps/desktop/src/routes/__root.tsx (1)

58-58: LGTM: Navigation event handling updated correctly.

The change properly includes the search property from the payload, aligning with the new structured navigation event format.

packages/utils/src/navigation.ts (1)

25-25: LGTM: Navigation call updated to structured format.

The change correctly updates the navigation call to use the new structured object format with explicit path and search properties, maintaining the same functionality while aligning with the standardized navigation event handling.

apps/desktop/src/components/toast/model-select.tsx (1)

18-28: LGTM: Well-structured refactoring with updated navigation format.

The extraction of the handleClick function improves readability and the navigation call correctly uses the new structured format with explicit path and search properties. The type-safe URL construction using LinkProps is a nice touch.

plugins/windows/src/commands.rs (3)

1-1: LGTM: Import updated correctly for structured navigation.

The addition of the events module import is necessary to support the new Navigate event structure.


104-104: LGTM: Function signature updated to use structured navigation.

The parameter change from String to events::Navigate provides better type safety and structure for navigation events.


106-106: LGTM: Function call updated to match new signature.

The function call correctly passes the event parameter to match the updated signature.

plugins/tray/src/ext.rs (1)

164-172: LGTM: AppNew handler correctly updated to structured navigation.

The navigation structure change is consistent with the TrayStart handler and correctly uses search: None for navigation without query parameters.

apps/desktop/src/components/right-panel/components/chat/empty-chat-state.tsx (2)

2-6: LGTM: Import organization improved.

The import reordering enhances code organization and the LinkProps type import is necessary for the type-safe navigation parameters.


25-25: LGTM: Excellent type safety with satisfies operator.

The use of as const satisfies LinkProps provides strong type safety while preserving literal types for the navigation parameters.

@yujonglee
Copy link
Contributor Author

#1223

@yujonglee yujonglee closed this Jul 27, 2025
@yujonglee yujonglee deleted the membership-keygen branch July 27, 2025 20:38
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