Skip to content

ADFA-3849: Add icon support to plugin MenuItem#1309

Merged
Daniel-ADFA merged 2 commits into
stagefrom
ADFA-3849
May 15, 2026
Merged

ADFA-3849: Add icon support to plugin MenuItem#1309
Daniel-ADFA merged 2 commits into
stagefrom
ADFA-3849

Conversation

@Daniel-ADFA
Copy link
Copy Markdown
Contributor

No description provided.

@Daniel-ADFA Daniel-ADFA requested a review from a team May 14, 2026 17:45
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8d572abd-133f-4fe4-b3b1-fb5725b4132f

📥 Commits

Reviewing files that changed from the base of the PR and between 5dbbdea and d53402a.

📒 Files selected for processing (1)
  • plugin-api/src/main/kotlin/com/itsaky/androidide/plugins/extensions/UIExtension.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugin-api/src/main/kotlin/com/itsaky/androidide/plugins/extensions/UIExtension.kt

📝 Walkthrough
  • Features

    • Plugin menu items can now display custom icons. Icons passed via MenuItem.icon are resolved from plugin resources using PluginDrawableResolver; if resolution fails or no icon is provided, the UI falls back to the default R.drawable.ic_package.
    • MenuItem constructor now includes an optional icon: Int? parameter (default null).
    • Added @JvmOverloads to MenuItem constructor to improve Java callers' ergonomics with default parameters.
  • Changes

    • app: PluginActionItem uses PluginDrawableResolver.resolve(...) to obtain plugin-specific drawables when a MenuItem.icon is supplied; otherwise uses the package default.
    • plugin-api: MenuItem data class signature updated with icon: Int? = null and annotated with @JvmOverloads.
  • Risks / Best-practice considerations

    • API compatibility: The MenuItem constructor signature changed. Although the new icon parameter is optional, callers that rely on positional-argument ordering, reflection, or binary compatibility may be affected.
    • Resource resolution failure: If plugins supply icon resource IDs that cannot be resolved for the host context, the system silently falls back to the default package icon—this may hide plugin packaging/resource issues.
    • Nullability & Java interop: icon is nullable; Java callers must explicitly handle nullable behavior when constructing MenuItem (the @JvmOverloads annotation mitigates some but not all interop pitfalls).
    • Security/validation: Plugin-supplied resource IDs are resolved at runtime; ensure untrusted plugins cannot cause unexpected drawable loading or resource collisions.

Walkthrough

MenuItem data model gains an optional icon field with Java interoperability annotations. PluginActionItem is updated to resolve plugin-specific drawable icons based on menu item metadata, using a default package icon as fallback.

Changes

Plugin Action Icon Resolution

Layer / File(s) Summary
Menu item icon contract
plugin-api/src/main/kotlin/com/itsaky/androidide/plugins/extensions/UIExtension.kt
MenuItem data class adds @JvmOverloads to its constructor and introduces a new optional icon: Int? = null property for storing drawable resource identifiers.
Plugin action icon resolution
app/src/main/java/com/itsaky/androidide/actions/PluginActionItem.kt
PluginActionItem imports PluginDrawableResolver and updates initialization to resolve plugin-specific drawable resources from menuItem.icon, falling back to R.drawable.ic_package when the icon is absent or resolution fails.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

Suggested reviewers

  • itsaky-adfa
  • dara-abijo-adfa
  • jatezzz

Poem

🐰 A tiny icon hunt in code tonight,
MenuItem whispers where drawables might,
PluginActionItem asks with care,
PluginDrawableResolver answers there,
Default box icon stays ready and bright.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to verify relevance to the changeset. Add a description explaining the purpose and details of adding icon support to plugin MenuItem.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding icon support to the plugin MenuItem class.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ADFA-3849

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
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.

🧹 Nitpick comments (2)
app/src/main/java/com/itsaky/androidide/actions/PluginActionItem.kt (1)

25-31: 💤 Low value

Simplify the icon resolution and fix indentation.

Two small things on this block:

  1. Line 25 has stray indentation (extra leading spaces) relative to the surrounding init block.
  2. The ContextCompat.getDrawable(context, R.drawable.ic_package) fallback is duplicated across both branches. An elvis chain expresses the intent more directly: "try to resolve the plugin icon; otherwise use the default."
♻️ Proposed simplification
     init {
         label = menuItem.title
-            val iconResId = menuItem.icon
-        icon = if (iconResId != null) {
-            PluginDrawableResolver.resolve(iconResId, pluginId, context)
-                ?: ContextCompat.getDrawable(context, R.drawable.ic_package)
-        } else {
-            ContextCompat.getDrawable(context, R.drawable.ic_package)
-        }
+        icon = menuItem.icon
+            ?.let { PluginDrawableResolver.resolve(it, pluginId, context) }
+            ?: ContextCompat.getDrawable(context, R.drawable.ic_package)
         location = ActionItem.Location.EDITOR_TOOLBAR
         requiresUIThread = true
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/main/java/com/itsaky/androidide/actions/PluginActionItem.kt` around
lines 25 - 31, Remove the stray leading spaces in the init block and simplify
the icon resolution by replacing the two-branch null-check with a single elvis
chain: get the menuItem.icon into iconResId, then set icon =
PluginDrawableResolver.resolve(iconResId, pluginId, context) ?:
ContextCompat.getDrawable(context, R.drawable.ic_package); ensure indentation
matches surrounding init block and reference PluginDrawableResolver.resolve,
iconResId, pluginId, context, and R.drawable.ic_package when making the change.
plugin-api/src/main/kotlin/com/itsaky/androidide/plugins/extensions/UIExtension.kt (1)

52-69: 💤 Low value

Consider documenting the new icon field and annotating it as a drawable resource.

Minor consistency nit: the tooltipTag field has KDoc explaining its semantics, but the new icon field lacks documentation describing that it's expected to be a plugin-owned drawable resource id (resolved via PluginDrawableResolver in PluginActionItem). Without this context, plugin authors may pass an IDE-internal R.drawable.* id and be surprised when resolution falls back to the default package icon.

Also, since icon represents a drawable resource id, annotating it with @DrawableRes would improve type safety for Kotlin callers. (Note: NavigationItem.icon, ToolbarAction.icon, and FabAction.icon in this same file also lack @DrawableRes — this could be applied consistently or deferred.)

✏️ Proposed docs/annotation addition
     val tooltipTag: String? = null,
-    val icon: Int? = null,
+    /**
+     * Optional drawable resource id from the plugin's resources, used as the
+     * icon for this menu item on toolbar/menu surfaces. The id is resolved
+     * against the plugin's package via `PluginDrawableResolver`; if resolution
+     * fails or this is null, the IDE falls back to a default icon.
+     */
+    `@androidx.annotation.DrawableRes`
+    val icon: Int? = null,
 )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@plugin-api/src/main/kotlin/com/itsaky/androidide/plugins/extensions/UIExtension.kt`
around lines 52 - 69, The new MenuItem.icon field lacks documentation and a
drawable resource annotation; add KDoc to MenuItem.icon clarifying that it must
be a plugin-owned drawable resource id (resolved via PluginDrawableResolver in
PluginActionItem) to avoid passing IDE-internal R.drawable ids, and annotate the
property with `@DrawableRes` (importing the annotation), and apply the same
KDoc/@DrawableRes change to NavigationItem.icon, ToolbarAction.icon, and
FabAction.icon for consistency across this file.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@app/src/main/java/com/itsaky/androidide/actions/PluginActionItem.kt`:
- Around line 25-31: Remove the stray leading spaces in the init block and
simplify the icon resolution by replacing the two-branch null-check with a
single elvis chain: get the menuItem.icon into iconResId, then set icon =
PluginDrawableResolver.resolve(iconResId, pluginId, context) ?:
ContextCompat.getDrawable(context, R.drawable.ic_package); ensure indentation
matches surrounding init block and reference PluginDrawableResolver.resolve,
iconResId, pluginId, context, and R.drawable.ic_package when making the change.

In
`@plugin-api/src/main/kotlin/com/itsaky/androidide/plugins/extensions/UIExtension.kt`:
- Around line 52-69: The new MenuItem.icon field lacks documentation and a
drawable resource annotation; add KDoc to MenuItem.icon clarifying that it must
be a plugin-owned drawable resource id (resolved via PluginDrawableResolver in
PluginActionItem) to avoid passing IDE-internal R.drawable ids, and annotate the
property with `@DrawableRes` (importing the annotation), and apply the same
KDoc/@DrawableRes change to NavigationItem.icon, ToolbarAction.icon, and
FabAction.icon for consistency across this file.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3ecff043-ef42-4d5a-9d5c-899f8a490d5e

📥 Commits

Reviewing files that changed from the base of the PR and between 7736433 and 5dbbdea.

📒 Files selected for processing (2)
  • app/src/main/java/com/itsaky/androidide/actions/PluginActionItem.kt
  • plugin-api/src/main/kotlin/com/itsaky/androidide/plugins/extensions/UIExtension.kt

@Daniel-ADFA Daniel-ADFA merged commit ad9f3d5 into stage May 15, 2026
2 checks passed
@Daniel-ADFA Daniel-ADFA deleted the ADFA-3849 branch May 15, 2026 15:45
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.

2 participants