Skip to content

Comments

refactor(mpp-idea): extract CodeReview components into separate files#21

Merged
phodal merged 3 commits intomasterfrom
refactor/code-review-components
Dec 1, 2025
Merged

refactor(mpp-idea): extract CodeReview components into separate files#21
phodal merged 3 commits intomasterfrom
refactor/code-review-components

Conversation

@phodal
Copy link
Member

@phodal phodal commented Dec 1, 2025

Summary

Split IdeaCodeReviewContent.kt (1915 lines) into 4 focused component files for better code organization and maintainability.

Changes

File Structure

File Lines Description
IdeaCodeReviewContent.kt 78 Main entry point with three-panel layout
IdeaCommitComponents.kt 569 Commit list and commit info components
IdeaDiffComponents.kt 251 Diff viewer and file tree components
IdeaAnalysisComponents.kt 219 AI analysis and lint result components

Components Extracted

IdeaCommitComponents.kt:

  • CommitListPanel - Commit list panel
  • CommitItem - Single commit item
  • IdeaCommitInfoCard - Commit info card
  • IdeaIssueIndicator - Issue indicator
  • IdeaInlineIssueChip - Issue chip
  • IdeaIssueInfoCard - Issue details card

IdeaDiffComponents.kt:

  • DiffViewerPanel - Diff view panel
  • IdeaFileViewMode - File view mode enum
  • IdeaCompactFileListView - Compact file list view
  • IdeaDiffHunkView / IdeaDiffLineView - Diff line views
  • IdeaFileTreeView - File tree view
  • FileTreeNode - File tree node

IdeaAnalysisComponents.kt:

  • IdeaAIAnalysisPanel - AI analysis panel
  • IdeaAnalysisHeader - Analysis header
  • IdeaLintAnalysisCard - Lint analysis card
  • IdeaAIAnalysisSection - AI analysis section
  • IdeaModificationPlanSection - Modification plan section
  • IdeaUserInputSection - User input section
  • IdeaSuggestedFixesSection - Suggested fixes section
  • IdeaCollapsibleCard - Collapsible card
  • IdeaBadge - Badge component

Testing

  • Build passes: cd mpp-idea && ../gradlew compileKotlin

Pull Request opened by Augment Code with guidance from the PR author

Summary by CodeRabbit

  • New Features
    • AI-assisted code review UI: lint results, AI analysis, modification plans, suggested fixes, and user feedback input.
    • Enhanced commit review panel with issue indicators and detailed commit info.
    • Diff viewer with List and Tree modes for flexible file/hunk navigation.
  • Refactor
    • UI wiring consolidated to simplify integration and streamline the code review tool window.
  • UX
    • Improved progress indicators, loading/empty states, and error/ retry affordances.

✏️ Tip: You can customize this high-level summary in your review settings.

Split IdeaCodeReviewContent.kt (1915 lines) into 4 focused component files:

- IdeaCodeReviewContent.kt (78 lines): Main entry point with three-panel layout
- IdeaCommitComponents.kt (569 lines): Commit list and commit info components
- IdeaDiffComponents.kt (251 lines): Diff viewer and file tree components
- IdeaAnalysisComponents.kt (219 lines): AI analysis and lint result components

This improves code organization and maintainability by separating concerns.
@coderabbitai
Copy link

coderabbitai bot commented Dec 1, 2025

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

💤 Files selected but had no reviewable changes (1)
  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/renderer/markdown/JewelMarkdownRenderer.kt

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Refactors the IDE code-review UI by extracting commit, diff, and AI-analysis UI into three new internal Compose component files and consolidating the public API surface in IdeaCodeReviewContent, which now wires the split-pane layout to those new modules.

Changes

Cohort / File(s) Change Summary
AI analysis components
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaAnalysisComponents.kt
New file adding internal Compose UI for AI-assisted code review: IdeaAIAnalysisPanel, IdeaAnalysisHeader, lint cards (file/issue rows), AI analysis / modification plan / user-input / suggested-fixes sections, and UI primitives (IdeaCollapsibleCard, IdeaBadge).
Commit review components
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaCommitComponents.kt
New file adding internal Compose UI for commits: CommitListPanel, CommitItem, IdeaCommitInfoCard (single/multiple views), IdeaIssueIndicator and variants, IdeaInlineIssueChip, IdeaIssueInfoCard, and related helpers for selection/refresh/token actions.
Diff viewer components
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaDiffComponents.kt
New file adding internal Compose UI for diffs: DiffViewerPanel, view-mode controls (LIST/TREE), IdeaCompactFileListView and IdeaFileTreeView, IdeaDiffHunkView/IdeaDiffLineView, FileTreeNode sealed class and buildFileTreeStructure helper, plus tree/list item components.
Public API consolidation
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaCodeReviewContent.kt
Major refactor: reduced exported/public composable declarations (removed 20+ previously exported items), leaving IdeaCodeReviewContent to compose the split-pane layout that references the new internal component files; imports simplified.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45–75 minutes

  • Pay attention to public API surface changes in IdeaCodeReviewContent.kt to ensure no downstream breakage.
  • Verify state and event wiring between IdeaCodeReviewContent and the three new component files (state propagation, callbacks, disposables).
  • Inspect Diff file-tree builder and diff-line rendering for correctness (FileTreeNode, buildFileTreeStructure, IdeaDiffHunkView, IdeaDiffLineView).
  • Check AI-analysis components for lifecycle/disposable handling (IdeaAIAnalysisPanel, IdeaAIAnalysisSection, parentDisposable usage) and loading/error states.

Possibly related PRs

Poem

🐰 A Rabbit’s Review Hop

I hopped through files with nimble paws,
Split a monolith without a pause.
Commits, diffs, and AI in three,
Neat panels now for all to see.
🍃✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.51% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: extracting CodeReview components from a monolithic file into four separate, focused files for improved code organization and maintainability.

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

Copy link

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

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

Review completed. 1 suggestions posted.

Comment augment review to trigger a new review at any time.

Text(line.oldLineNumber?.toString()?.padStart(4) ?: " ", style = JewelTheme.defaultTextStyle.copy(fontFamily = FontFamily.Monospace, fontSize = 10.sp, color = JewelTheme.globalColors.text.info.copy(alpha = 0.5f)))
Text(line.newLineNumber?.toString()?.padStart(4) ?: " ", style = JewelTheme.defaultTextStyle.copy(fontFamily = FontFamily.Monospace, fontSize = 10.sp, color = JewelTheme.globalColors.text.info.copy(alpha = 0.5f)))
Text(prefix, style = JewelTheme.defaultTextStyle.copy(fontFamily = FontFamily.Monospace, fontSize = 10.sp, color = textColor, fontWeight = FontWeight.Bold))
Text(line.content, style = JewelTheme.defaultTextStyle.copy(fontFamily = FontFamily.Monospace, fontSize = 10.sp, color = textColor))
Copy link

Choose a reason for hiding this comment

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

prefix is rendered separately and line.content appears to still include the leading diff symbol, so the +/- marker will be shown twice. Consider stripping the prefix from line.content to avoid duplication (this was done previously).

🤖 Was this useful? React with 👍 or 👎

Copy link
Member Author

Choose a reason for hiding this comment

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

The code is correct - no duplication occurs.

Looking at DiffParser.parseHunk() in mpp-core/src/commonMain/kotlin/cc/unitmesh/agent/diff/DiffModels.kt (lines 290, 302, 312), the DiffLine.content is created using line.substring(1), which already strips the leading +/-/ prefix from the raw diff line.

So:

  • prefix is generated based on line.type (e.g., "+" for ADDED)
  • line.content contains only the actual content without the prefix

No fix needed here.

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 (2)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaDiffComponents.kt (1)

200-210: Consider using file path as key instead of index.

Using index in the key ("file_${node.path}_$index") can cause recomposition issues if files within a directory are reordered or removed. The file path is already unique within a directory.

                     if (expandedDirs.contains(node.path)) {
-                        node.files.forEachIndexed { index, file ->
-                            item(key = "file_${node.path}_$index") {
+                        node.files.forEach { file ->
+                            item(key = "file_${file.path}") {
                                 IdeaFileTreeItemCompact(file, expandedFilePath == file.path, { expandedFilePath = if (expandedFilePath == file.path) null else file.path }, onViewFile, 1)
                             }
                         }
                     }
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaCodeReviewContent.kt (1)

61-61: Address or track the TODO for token configuration.

The TODO /* TODO: Open token configuration */ should be implemented or tracked in an issue to avoid being forgotten.

Would you like me to open an issue to track implementing the token configuration callback?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e389d4 and 9a65f2d.

📒 Files selected for processing (4)
  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaAnalysisComponents.kt (1 hunks)
  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaCodeReviewContent.kt (1 hunks)
  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaCommitComponents.kt (1 hunks)
  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaDiffComponents.kt (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.kt

📄 CodeRabbit inference engine (AGENTS.md)

Use expect/actual for platform-specific code in KMP projects (e.g., file I/O on JVM/JS/Wasm)

Files:

  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaCommitComponents.kt
  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaDiffComponents.kt
  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaAnalysisComponents.kt
  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaCodeReviewContent.kt
🧠 Learnings (1)
📚 Learning: 2025-11-30T02:30:49.805Z
Learnt from: CR
Repo: phodal/auto-dev-sketch PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-30T02:30:49.805Z
Learning: Applies to **/src/{androidMain,desktopMain}/**/*.kt : For Compose (Desktop/Android), use `AutoDevColors` from `cc.unitmesh.devins.ui.compose.theme` or `MaterialTheme.colorScheme`

Applied to files:

  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaCommitComponents.kt
  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaDiffComponents.kt
  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaAnalysisComponents.kt
  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaCodeReviewContent.kt
🧬 Code graph analysis (1)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaDiffComponents.kt (1)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaCommitComponents.kt (1)
  • IdeaCommitInfoCard (139-169)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Build (241)
  • GitHub Check: Build (223)
🔇 Additional comments (6)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaAnalysisComponents.kt (1)

38-71: Well-structured AI analysis panel orchestration.

The IdeaAIAnalysisPanel cleanly orchestrates the analysis workflow with appropriate state-driven visibility for each section. The use of LazyColumn for scrollable content is appropriate.

mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaCommitComponents.kt (2)

229-262: Verify ordering assumption for commit range display.

Lines 230-231 assume selectedCommits.first() is the newest and selectedCommits.last() is the oldest. This depends on the caller maintaining chronological order.

Consider adding a defensive sort or documenting this contract:

 @Composable
 private fun MultipleCommitsInfoView(selectedCommits: List<CommitInfo>) {
-    val newest = selectedCommits.first()
-    val oldest = selectedCommits.last()
+    // Assumes selectedCommits is ordered newest-first; if not guaranteed, sort by date
+    val newest = selectedCommits.first()
+    val oldest = selectedCommits.last()

26-81: Clean commit list implementation with proper state handling.

Good handling of loading, empty, and populated states. The use of LazyColumn with rememberLazyListState() is appropriate for potentially long commit lists.

mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaDiffComponents.kt (2)

176-188: File tree structure ordering is clear.

Root-level files appear first, followed by directories sorted alphabetically. This is a reasonable UX choice. The logic correctly handles edge cases like empty directory strings.


39-60: Well-designed panel orchestration.

DiffViewerPanel cleanly composes the commit info card, header, and content area. The view mode state is appropriately local to this component.

mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaCodeReviewContent.kt (1)

20-77: Excellent refactoring outcome.

The file is now a clean 77-line orchestrator that composes the three-panel layout using the extracted components. The nested IdeaResizableSplitPane structure clearly expresses the UI hierarchy. This is a significant improvement from the original 1915 lines.

…tionPlanSection

Address PR review comment by removing the unused parameter.
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: 0

🧹 Nitpick comments (1)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaAnalysisComponents.kt (1)

138-138: Consider dynamic width for line numbers.

The fixed 40.dp width works for most files but may truncate line numbers beyond L9999. Consider using Modifier.widthIn(min = 40.dp) for better layout adaptability.

-        Text("L${issue.line}", style = JewelTheme.defaultTextStyle.copy(fontFamily = FontFamily.Monospace, fontSize = 10.sp, color = if (isInModifiedRange) severityColor else JewelTheme.globalColors.text.info), modifier = Modifier.width(40.dp))
+        Text("L${issue.line}", style = JewelTheme.defaultTextStyle.copy(fontFamily = FontFamily.Monospace, fontSize = 10.sp, color = if (isInModifiedRange) severityColor else JewelTheme.globalColors.text.info), modifier = Modifier.widthIn(min = 40.dp))
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a65f2d and d7207ce.

📒 Files selected for processing (1)
  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaAnalysisComponents.kt (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.kt

📄 CodeRabbit inference engine (AGENTS.md)

Use expect/actual for platform-specific code in KMP projects (e.g., file I/O on JVM/JS/Wasm)

Files:

  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaAnalysisComponents.kt
🧠 Learnings (1)
📚 Learning: 2025-11-30T02:30:49.805Z
Learnt from: CR
Repo: phodal/auto-dev-sketch PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-30T02:30:49.805Z
Learning: Applies to **/src/{androidMain,desktopMain}/**/*.kt : For Compose (Desktop/Android), use `AutoDevColors` from `cc.unitmesh.devins.ui.compose.theme` or `MaterialTheme.colorScheme`

Applied to files:

  • mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaAnalysisComponents.kt
⏰ 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: Build (241)
  • GitHub Check: Build (223)
🔇 Additional comments (7)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/codereview/IdeaAnalysisComponents.kt (7)

1-36: LGTM! Proper theming setup.

The imports are well-organized, and the use of AutoDevColors from cc.unitmesh.devins.ui.compose.theme aligns with the project's theming guidelines for Compose Desktop/Android.

Based on learnings, this follows the recommended approach for theming in Compose.


38-71: Well-structured state-driven UI.

The panel correctly orchestrates the AI analysis workflow with appropriate conditional rendering based on AnalysisStage. The use of LazyColumn ensures good performance, and the empty state provides clear guidance to users.


73-102: LGTM! Clear status communication.

The header provides clear visual feedback for each analysis stage and correctly enables/disables the "Start Review" button based on the availability of diff files.


104-122: LGTM! Comprehensive lint result display.

The component correctly aggregates counts, displays badges only when relevant, and provides a fallback for raw lint output when structured results aren't available.


146-160: LGTM! Clean AI output sections.

Both sections correctly render AI-generated content with appropriate loading states and collapsible UI. The previously flagged unused parameter has been addressed.


162-175: LGTM! User input flow is clear.

The section correctly captures user feedback and provides clear CTAs. The hardcoded expansion (isExpanded = true) is intentional to ensure visibility of the action-required step.


177-218: LGTM! Well-crafted utility components.

The suggested fixes section handles all states appropriately, and the collapsible card provides a clean, reusable UI primitive with smooth animations and clear visual feedback.

@phodal
Copy link
Member Author

phodal commented Dec 1, 2025

augment review

Renamed the file for clarity and consistency with naming conventions.
Copy link

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

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

Review completed. No suggestions at this time.

Comment augment review to trigger a new review at any time.

@phodal phodal merged commit 909c92f into master Dec 1, 2025
4 of 5 checks passed
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