Skip to content

Conversation

devdezzies
Copy link
Owner

@devdezzies devdezzies commented Jul 1, 2025

Summary by CodeRabbit

  • New Features

    • Added theme management with support for light, dark, and system preferences, including a user-accessible theme switcher in the project header.
    • Introduced a new project header with navigation and appearance settings.
    • Implemented a loading indicator with animated messages for message loading states.
    • Enabled fragment selection and interactivity within project messages, allowing users to highlight and interact with specific message fragments.
  • Improvements

    • Messages now refresh automatically every 5 seconds for up-to-date content.
    • Enhanced message container to visually indicate the active fragment and provide smoother user interaction.
    • Improved layout to support system-based theme switching and suppress hydration warnings for better user experience.

Copy link

coderabbitai bot commented Jul 1, 2025

Walkthrough

This update introduces theme management to the layout using next-themes, adds a ProjectHeader with theme-switching UI, and implements a new MessageLoading component. The MessagesContainer and related message card components are refactored to support fragment click handling and active fragment state, with state sharing between header and message container in the ProjectView.

Changes

File(s) Change Summary
src/app/layout.tsx Added ThemeProvider for theme management, updated <html> with hydration warning suppression.
src/modules/projects/ui/components/message-card.tsx Enabled onFragmentClick callback propagation for fragment interaction in message cards.
src/modules/projects/ui/components/message-loading.tsx Introduced new MessageLoading component with animated cycling messages and logo.
src/modules/projects/ui/components/messages-container.tsx Added active fragment state/handler props, logic for setting active fragment, fragment click handling, and conditional loading UI.
src/modules/projects/ui/components/project-header.tsx Added new ProjectHeader component with project info and theme-switching dropdown menu.
src/modules/projects/ui/views/project-view.tsx Added activeFragment state, included ProjectHeader, and passed fragment state to MessagesContainer for interactivity.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ProjectView
    participant ProjectHeader
    participant MessagesContainer
    participant MessageCard
    participant FragmentCard

    User->>ProjectView: Access project view
    ProjectView->>ProjectHeader: Render with projectId
    ProjectView->>MessagesContainer: Render with activeFragment state
    MessagesContainer->>MessageCard: Render each message
    MessageCard->>FragmentCard: Pass onFragmentClick
    User->>FragmentCard: Click fragment
    FragmentCard->>MessageCard: Trigger onFragmentClick(fragment)
    MessageCard->>MessagesContainer: Update activeFragment
    MessagesContainer->>ProjectView: setActiveFragment(fragment)
Loading
sequenceDiagram
    participant User
    participant ProjectHeader
    participant ThemeProvider

    User->>ProjectHeader: Open appearance menu
    ProjectHeader->>ThemeProvider: Change theme (light/dark/system)
    ThemeProvider-->>User: UI updates to selected theme
Loading

Possibly related PRs

  • 10: added ui messages #9: Introduces the initial MessagesContainer and MessageCard components; this PR directly extends those components by adding fragment interaction and state handling.

Poem

In a meadow of code, a rabbit hops with glee,
Themes now switch from dark to light, as easy as can be!
Fragments click and shimmer, messages load and spin,
Project headers gleam above, let the coding fun begin.
With every hop and feature, our warren grows anew—
Hooray for these changes, from this bunny to you!
🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-07-01T05_50_53_487Z-debug-0.log


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b47e583 and 311c613.

📒 Files selected for processing (1)
  • src/modules/projects/ui/components/messages-container.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/modules/projects/ui/components/messages-container.tsx
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • 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 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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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

@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 (3)
src/modules/projects/ui/components/project-header.tsx (2)

2-2: Consider splitting the long import for better readability.

This import line is quite long and could be split across multiple lines for better maintainability.

-import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
+import { 
+  DropdownMenu, 
+  DropdownMenuContent, 
+  DropdownMenuItem, 
+  DropdownMenuPortal, 
+  DropdownMenuRadioGroup, 
+  DropdownMenuRadioItem, 
+  DropdownMenuSeparator, 
+  DropdownMenuSub, 
+  DropdownMenuSubContent, 
+  DropdownMenuSubTrigger, 
+  DropdownMenuTrigger 
+} from "@/components/ui/dropdown-menu";

27-33: Add error handling for missing logo asset.

Consider adding error handling for the logo image in case /logo.svg is missing or fails to load.

 <Image
     src="/logo.svg"
     alt="Neo logo"
     width={15}
     height={15}
     className="shrink-0"
+    onError={(e) => {
+        e.currentTarget.style.display = 'none';
+    }}
 />
src/modules/projects/ui/components/message-loading.tsx (1)

5-15: Move messages array outside component to prevent recreation.

The messages array is being recreated on every render. Consider moving it outside the component for better performance.

+const LOADING_MESSAGES = [
+    "Thinking...", 
+    "Loading...", 
+    "Generating...", 
+    "Analyzing your request...", 
+    "Building your website", 
+    "Crafting components...", 
+    "Optimizing layout...",
+    "Adding final touches...", 
+    "Almost ready..."
+];

 const ShimmerMessages = () => {
-    const messages = [
-        "Thinking...", 
-        "Loading...", 
-        "Generating...", 
-        "Analyzing your request...", 
-        "Building your website", 
-        "Crafting components...", 
-        "Optimizing layout...",
-        "Adding final touches...", 
-        "Almost ready..."
-    ]; 
+    const messages = LOADING_MESSAGES;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a927db3 and b47e583.

📒 Files selected for processing (6)
  • src/app/layout.tsx (2 hunks)
  • src/modules/projects/ui/components/message-card.tsx (3 hunks)
  • src/modules/projects/ui/components/message-loading.tsx (1 hunks)
  • src/modules/projects/ui/components/messages-container.tsx (2 hunks)
  • src/modules/projects/ui/components/project-header.tsx (1 hunks)
  • src/modules/projects/ui/views/project-view.tsx (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/modules/projects/ui/components/message-card.tsx (1)
src/lib/utils.ts (1)
  • cn (4-6)
src/modules/projects/ui/views/project-view.tsx (2)
src/modules/projects/ui/components/project-header.tsx (1)
  • ProjectHeader (10-71)
src/modules/projects/ui/components/messages-container.tsx (1)
  • MessagesContainer (11-73)
src/modules/projects/ui/components/messages-container.tsx (2)
src/trpc/server.tsx (1)
  • trpc (10-14)
src/modules/projects/ui/components/message-loading.tsx (1)
  • MessageLoading (36-56)
🔇 Additional comments (18)
src/app/layout.tsx (3)

6-6: Good choice for theme management.

The next-themes package is well-maintained and provides excellent SSR support for theme switching.


30-30: Correct hydration warning suppression.

The suppressHydrationWarning attribute is necessary here to prevent React hydration mismatches when the server-rendered theme differs from the client-side theme preference.


34-42: Well-configured ThemeProvider setup.

The configuration is optimal:

  • attribute="class" enables CSS class-based theme switching
  • defaultTheme="system" respects user's OS preference
  • enableSystem allows automatic system theme detection
  • disableTransitionOnChange prevents jarring animations during theme switches
src/modules/projects/ui/components/project-header.tsx (3)

12-14: Excellent use of useSuspenseQuery with TRPC.

The integration between TRPC query options and React Query's useSuspenseQuery is clean and type-safe.


53-53: Well-implemented theme state management.

The DropdownMenuRadioGroup with value={theme} and onValueChange={setTheme} provides excellent UX for theme selection with proper state synchronization.


25-25: No action needed: Tailwind CSS v4 supports the ! important modifier

The project’s package.json specifies Tailwind CSS ^4, and the trailing ! syntax was introduced in v3.2. Your pl-2! utility is valid and will apply padding-left: 0.5rem !important.

src/modules/projects/ui/components/message-card.tsx (3)

45-50: Excellent fragment click handling implementation.

The button properly triggers the callback and uses conditional styling to indicate active state. The cn utility correctly handles the dynamic classes for visual feedback.


99-99: Proper callback propagation through component hierarchy.

The onFragmentClick callback is now correctly passed from AssistantMessage to FragmentCard, enabling proper event handling.


127-127: Clean prop threading completed.

The callback is properly passed from MessageCard to AssistantMessage, completing the event handling chain from UI button to parent component.

src/modules/projects/ui/components/message-loading.tsx (2)

19-25: Proper interval cleanup implementation.

The useEffect correctly sets up and cleans up the interval to prevent memory leaks. Good React practices followed.


36-55: Clean and consistent UI structure.

The component structure matches the styling patterns used in other message components, maintaining visual consistency.

src/modules/projects/ui/components/messages-container.tsx (3)

30-37: Solid logic for active fragment management.

The effect correctly identifies the last assistant message with a fragment and sets it as active. The dependency array is appropriate.


57-58: Well-implemented fragment interaction handling.

The active fragment comparison and click handler provide clean state management for fragment selection.


62-62: Good UX enhancement with conditional loading state.

Showing the loading component when the last message is from a user provides clear feedback about the system processing the request.

src/modules/projects/ui/views/project-view.tsx (4)

11-13: LGTM! Clean import additions.

The new imports are necessary and correctly added:

  • Suspense and useState for React functionality
  • Fragment type for proper TypeScript typing
  • ProjectHeader component for the new header functionality

20-20: Excellent state management implementation.

The activeFragment state is properly typed as Fragment | null and positioned appropriately in the component hierarchy to enable sharing between the ProjectHeader and MessagesContainer components.


30-32: Good use of Suspense boundary for ProjectHeader.

The ProjectHeader component is properly wrapped in its own Suspense boundary with an appropriate fallback message, ensuring good loading states and user experience.


34-38: Well-structured props passing for state sharing.

The MessagesContainer now correctly receives the activeFragment state and setter, enabling proper communication between parent and child components. The prop types match the expected interface from the relevant code snippets.

Comment on lines 24 to 27
}, {
// TODO: THIS ACTUALLY REFETCHES EVERYTIME, FIX LATER
refetchInterval: 5000,
}));
Copy link

@coderabbitai coderabbitai bot Jul 1, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Address the performance impact of frequent refetching.

The 5-second refetch interval could impact performance and increase server load, especially with multiple concurrent users. The TODO comment indicates awareness of the issue.

Consider implementing WebSocket or Server-Sent Events for real-time message updates instead of polling:

// Alternative approach using WebSocket or SSE
const { data: messages } = useSuspenseQuery(trpc.messages.getMany.queryOptions({
    projectId: projectId
}));

// Add real-time subscription
useEffect(() => {
    const unsubscribe = trpc.messages.onNewMessage.subscribe(
        { projectId },
        {
            onData: (newMessage) => {
                // Invalidate query to refetch messages
                trpc.messages.getMany.invalidate({ projectId });
            }
        }
    );
    return unsubscribe;
}, [projectId]);
🤖 Prompt for AI Agents
In src/modules/projects/ui/components/messages-container.tsx around lines 24 to
27, the current use of a 5-second refetchInterval causes frequent polling that
can degrade performance and increase server load. To fix this, replace the
polling mechanism with a real-time update approach using WebSocket or
Server-Sent Events. Implement a subscription to new messages via
trpc.messages.onNewMessage that triggers invalidation and refetching of the
messages query only when new data arrives, eliminating the need for periodic
polling.

Copy link

Choose a reason for hiding this comment

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

@devdezzies I'll help you create a tRPC handler for onNewMessage to replace the polling mechanism with real-time updates. Let me first examine the existing tRPC structure to understand where to implement this properly.

coderabbitai bot added a commit that referenced this pull request Jul 1, 2025
Docstrings generation was requested by @devdezzies.

* #10 (comment)

The following files were modified:

* `src/app/layout.tsx`
* `src/modules/projects/ui/components/message-card.tsx`
* `src/modules/projects/ui/components/message-loading.tsx`
* `src/modules/projects/ui/components/messages-container.tsx`
* `src/modules/projects/ui/components/project-header.tsx`
* `src/modules/projects/ui/views/project-view.tsx`
Copy link

coderabbitai bot commented Jul 1, 2025

Note

Generated docstrings for this pull request at #11

@devdezzies devdezzies added the enhancement New feature or request label Jul 1, 2025
@devdezzies devdezzies merged commit 01d843b into main Jul 1, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant