Skip to content

Comments

feat: add right-click context menu to sidebar plugin icons order to be able to remove a provider without going to the settings.#197

Open
MariosPapadakis wants to merge 1 commit intorobinebers:mainfrom
MariosPapadakis:feat/remove-plugin-with-right-menu
Open

feat: add right-click context menu to sidebar plugin icons order to be able to remove a provider without going to the settings.#197
MariosPapadakis wants to merge 1 commit intorobinebers:mainfrom
MariosPapadakis:feat/remove-plugin-with-right-menu

Conversation

@MariosPapadakis
Copy link

@MariosPapadakis MariosPapadakis commented Feb 19, 2026

Description

Adds a second action to the native right-click context menu provider icons in the sidebar:

  • Remove — disables the provider (same behavior as unchecking it in Settings)

Testing

  • `bun run build` — compiles cleanly
  • `bun run test` — all 571 tests pass (38 test files)
  • `tsc --noEmit` — no TypeScript errors
  • Manually verified both Reload and Remove actions work correctly via the tray panel

Screenshots

Before:

CleanShot 2026-02-20 at 00 15 44@2x

After:

CleanShot 2026-02-20 at 00 16 55@2x

Related Issue

New feature.

Type of Change

  • Bug fix
  • New feature
  • New provider plugin
  • Documentation
  • Performance improvement
  • Other (describe below)

Testing

  • I ran bun run build and it succeeded
  • I ran bun run test and all tests pass
  • I tested the change locally with bun tauri dev

Screenshots

Checklist

  • I read CONTRIBUTING.md
  • My PR targets the main branch
  • I did not introduce new dependencies without justification

Summary by cubic

Added a right-click context menu to sidebar provider icons with Reload and Remove, so you can disable a provider without opening Settings. Remove mirrors the Settings toggle and auto-returns to Home if the provider was active.

  • New Features
    • Right-click menu with Reload and Remove on provider icons.
    • Remove disables the provider, saves settings, updates the tray, and navigates to Home if needed.
    • Uses Tauri Menu API; added core:menu:default capability.

Written for commit c4c7736. Summary will update on new commits.

@github-actions github-actions bot added rust Pull requests that update rust code core labels Feb 19, 2026
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 3 files

Copy link
Owner

@robinebers robinebers left a comment

Choose a reason for hiding this comment

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

Hey! 👋 This is Rob's AI reviewer. Thanks for the contribution!

Nice feature and clean wiring. The new right-click flow feels great, and Remove matching Settings behavior is the right call. One thing to fix before merge:

  1. Please clean up menu resources after use — each right-click creates native menu objects (Menu, IconMenuItem, PredefinedMenuItem). Right now they are not closed, so memory can grow over time. Please close them in a finally block after menu.popup().

Example shape:

try {
  await menu.popup()
} finally {
  await Promise.allSettled([
    menu.close(),
    reloadItem.close(),
    separator.close(),
    removeItem.close(),
  ])
}

Everything else in this PR looks good to me.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a right-click context menu to sidebar plugin icons, allowing users to reload or remove (disable) providers without navigating to the Settings page. The implementation uses Tauri's Menu API to create native context menus with "Reload" and "Remove" actions.

Changes:

  • Added context menu functionality to plugin icons in the sidebar with Reload and Remove options
  • Integrated the remove action with existing plugin toggle logic and analytics tracking
  • Added core:menu:default capability to enable Tauri Menu API usage

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
src/components/side-nav.tsx Implements context menu creation and handling for plugin icons using Tauri Menu API
src/App.tsx Adds handlePluginContextAction callback to process reload and remove actions from the context menu
src-tauri/capabilities/default.json Enables core:menu:default permission for native menu functionality

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
}
},
[handleRetryPlugin, pluginSettings, scheduleTrayIconUpdate, activeView]
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

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

The dependency array is missing setPluginSettings and setActiveView. These state setters should be included in the dependency array even though they're stable in React, to maintain consistency with other callbacks in the codebase and follow React best practices. The existing handleToggle callback at line 904 follows the same pattern and includes all dependencies.

Suggested change
[handleRetryPlugin, pluginSettings, scheduleTrayIconUpdate, activeView]
[handleRetryPlugin, pluginSettings, scheduleTrayIconUpdate, activeView, setPluginSettings, setActiveView]

Copilot uses AI. Check for mistakes.
Comment on lines +80 to +98
;(async () => {
const reloadItem = await IconMenuItem.new({
id: `ctx-reload-${pluginId}`,
text: "Reload",
icon: NativeIcon.Refresh,
action: () => onPluginContextAction(pluginId, "reload"),
})
const separator = await PredefinedMenuItem.new({ item: "Separator" })
const removeItem = await IconMenuItem.new({
id: `ctx-remove-${pluginId}`,
text: "Remove",
icon: NativeIcon.Remove,
action: () => onPluginContextAction(pluginId, "remove"),
})
const menu = await Menu.new({
items: [reloadItem, separator, removeItem],
})
await menu.popup()
})().catch(console.error)
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

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

The menu creation happens on every context menu event but doesn't clean up the created menu items. This could lead to memory leaks over time. Consider cleaning up menu items after the menu is closed, or memoize the menu creation to reuse the same instances. Other parts of the codebase handle cleanup carefully (e.g., ResizeObserver and MutationObserver cleanup in App.tsx lines 951-955).

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

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

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +75 to +101
const handlePluginContextMenu = useCallback(
(e: React.MouseEvent, pluginId: string) => {
e.preventDefault()
if (!onPluginContextAction) return

;(async () => {
const reloadItem = await IconMenuItem.new({
id: `ctx-reload-${pluginId}`,
text: "Reload",
icon: NativeIcon.Refresh,
action: () => onPluginContextAction(pluginId, "reload"),
})
const separator = await PredefinedMenuItem.new({ item: "Separator" })
const removeItem = await IconMenuItem.new({
id: `ctx-remove-${pluginId}`,
text: "Remove",
icon: NativeIcon.Remove,
action: () => onPluginContextAction(pluginId, "remove"),
})
const menu = await Menu.new({
items: [reloadItem, separator, removeItem],
})
await menu.popup()
})().catch(console.error)
},
[onPluginContextAction]
)
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

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

The new context menu functionality lacks test coverage. The existing side-nav.test.tsx file tests other SideNav behaviors but doesn't include tests for the new onPluginContextAction callback. Consider adding tests to verify that the context menu handler is called correctly when right-clicking a plugin icon. The codebase follows comprehensive testing practices as evidenced by the existing test suite.

Copilot uses AI. Check for mistakes.
Comment on lines +907 to +935
const handlePluginContextAction = useCallback(
(pluginId: string, action: PluginContextAction) => {
if (action === "reload") {
handleRetryPlugin(pluginId)
} else if (action === "remove") {
// Disable the plugin (same as unchecking in settings)
if (!pluginSettings) return
const alreadyDisabled = pluginSettings.disabled.includes(pluginId)
if (alreadyDisabled) return

track("provider_toggled", { provider_id: pluginId, enabled: "false" })
const nextSettings: PluginSettings = {
...pluginSettings,
disabled: [...pluginSettings.disabled, pluginId],
}
setPluginSettings(nextSettings)
scheduleTrayIconUpdate("settings", TRAY_SETTINGS_DEBOUNCE_MS)
void savePluginSettings(nextSettings).catch((error) => {
console.error("Failed to save plugin toggle:", error)
})

// If we were viewing this plugin, switch to home
if (activeView === pluginId) {
setActiveView("home")
}
}
},
[handleRetryPlugin, pluginSettings, scheduleTrayIconUpdate, activeView]
)
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

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

The new handlePluginContextAction callback lacks test coverage. The existing App.test.tsx file extensively tests plugin toggling behavior (e.g., "enables disabled plugin and starts batch" at line 865), but there are no tests for the new context menu actions. Consider adding tests for both "reload" and "remove" actions, including edge cases like removing an already disabled plugin or removing the currently active plugin.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

@davidarny davidarny left a comment

Choose a reason for hiding this comment

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

LGTM! Just need a bit of test coverage 🤓

Copy link
Collaborator

@validatedev validatedev left a comment

Choose a reason for hiding this comment

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

I agree with @davidarny, need some testcov.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core rust Pull requests that update rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants