diff --git a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/actions/ContinuePluginActions.kt b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/actions/ContinuePluginActions.kt index d28d8258a28..cd802c079d0 100644 --- a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/actions/ContinuePluginActions.kt +++ b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/actions/ContinuePluginActions.kt @@ -2,6 +2,7 @@ package com.github.continuedev.continueintellijextension.actions import com.github.continuedev.continueintellijextension.HighlightedCodePayload import com.github.continuedev.continueintellijextension.RangeInFileWithContents +import com.github.continuedev.continueintellijextension.browser.ContinueBrowserService import com.github.continuedev.continueintellijextension.browser.ContinueBrowserService.Companion.getBrowser import com.github.continuedev.continueintellijextension.editor.DiffStreamService import com.github.continuedev.continueintellijextension.editor.EditorUtils @@ -9,9 +10,11 @@ import com.github.continuedev.continueintellijextension.services.ContinuePluginS import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.PlatformDataKeys +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.service import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.project.Project +import com.intellij.openapi.wm.ToolWindowManager import java.io.File class RestartContinueProcess : AnAction() { @@ -89,6 +92,39 @@ class OpenConfigAction : ContinueToolbarAction() { } } +class ReloadBrowserAction: ContinueToolbarAction() { + override fun toolbarActionPerformed(project: Project) { + val toolWindow = ToolWindowManager.getInstance(project).getToolWindow("Continue") + ?: return + val browserService = project.service() + + // Perform the reload and UI update on the Event Dispatch Thread + ApplicationManager.getApplication().invokeLater { + // Reload the browser service to get a new browser instance + browserService.reload() + + val newBrowser = project.getBrowser() ?: return@invokeLater + val newBrowserComponent = newBrowser.getComponent() + + val contentManager = toolWindow.contentManager + contentManager.removeAllContents(true) + + val newContent = contentManager.factory.createContent( + newBrowserComponent, + null, + false + ) + contentManager.addContent(newContent) + contentManager.setSelectedContent(newContent, true) // Request focus + + toolWindow.activate({ + // After activation, ensure the browser's input field gets focus + newBrowser.focusOnInput() + }, true) + } + } +} + class OpenLogsAction : AnAction() { override fun actionPerformed(e: AnActionEvent) { val project = e.project ?: return diff --git a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/browser/ContinueBrowserService.kt b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/browser/ContinueBrowserService.kt index 155d9ffe882..12736614038 100644 --- a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/browser/ContinueBrowserService.kt +++ b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/browser/ContinueBrowserService.kt @@ -1,6 +1,7 @@ package com.github.continuedev.continueintellijextension.browser import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.Service import com.intellij.openapi.components.service import com.intellij.openapi.project.Project @@ -8,16 +9,51 @@ import com.intellij.openapi.util.Disposer import com.intellij.ui.jcef.JBCefApp @Service(Service.Level.PROJECT) -class ContinueBrowserService(project: Project): Disposable { +class ContinueBrowserService(val project: Project): Disposable { - private val browser: ContinueBrowser? = - if (JBCefApp.isSupported()) - ContinueBrowser(project) - else null + private var browser: ContinueBrowser? = null + + init { + load() + } override fun dispose() { - if (browser != null) - Disposer.dispose(browser) + browser?.let { Disposer.dispose(it) } + browser = null + } + + private fun load(): ContinueBrowser? { + if (browser != null) { + return browser + } + if (!JBCefApp.isSupported()) { + return null + } + val newBrowser = ContinueBrowser(project) + Disposer.register(this, newBrowser) + + this.browser = newBrowser + return this.browser + } + + /** + * Reloads the browser by disposing the current one and creating a new one. + * This method is intended for use when browser is frozen (unresponsive). + */ + fun reload() { + // Store the old browser instance to be disposed later + val oldBrowser = browser + browser = null + + // Dispose the old browser after the new one is loaded and UI is updated. + // This avoids race conditions. We can do this on a background thread. + oldBrowser?.let { + ApplicationManager.getApplication().invokeLater { + Disposer.dispose(it) + } + } + + load() } companion object { diff --git a/extensions/intellij/src/main/resources/META-INF/plugin.xml b/extensions/intellij/src/main/resources/META-INF/plugin.xml index 7481b8abafc..3b04166d4a2 100644 --- a/extensions/intellij/src/main/resources/META-INF/plugin.xml +++ b/extensions/intellij/src/main/resources/META-INF/plugin.xml @@ -155,6 +155,14 @@ + + + + +