Skip to content

refactor: Optimized the components of the tool window #233

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.project.IndexNotReadyException
import com.intellij.openapi.wm.ToolWindowManager
import com.intellij.temporary.getElementToAction

class CodeCompleteChatAction : AnAction() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package cc.unitmesh.devti.actions.groups

import cc.unitmesh.devti.settings.LanguageChangedCallback
import cc.unitmesh.devti.settings.LanguageChangedCallback.presentationText
import com.intellij.openapi.actionSystem.ActionGroupUtil
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnActionEvent
Expand All @@ -18,8 +18,7 @@ import com.intellij.openapi.project.DumbAware
class AutoChatDynamicActionGroup : DefaultActionGroup(), DumbAware {

init {
LanguageChangedCallback.presentationText("autodev.chat",
templatePresentation.also { it.isHideGroupIfEmpty = true })
presentationText("autodev.chat", templatePresentation.also { it.isHideGroupIfEmpty = true }, 1)
}

override fun getActionUpdateThread() = ActionUpdateThread.BGT
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package cc.unitmesh.devti.gui

import cc.unitmesh.devti.AutoDevBundle
import cc.unitmesh.devti.gui.chat.ChatActionType
import cc.unitmesh.devti.gui.chat.ChatCodingPanel
import cc.unitmesh.devti.gui.chat.ChatCodingService
import cc.unitmesh.devti.settings.LanguageChangedCallback.componentStateChanged
import com.intellij.openapi.actionSystem.ex.ActionUtil
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
import com.intellij.openapi.wm.ToolWindow
import com.intellij.openapi.wm.ToolWindowFactory
import com.intellij.openapi.wm.ToolWindowManager
import com.intellij.ui.content.Content
import com.intellij.ui.content.ContentFactory

class AutoDevToolWindowFactory : ToolWindowFactory, DumbAware {
Expand All @@ -21,9 +22,9 @@ class AutoDevToolWindowFactory : ToolWindowFactory, DumbAware {
override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) {
val chatCodingService = ChatCodingService(ChatActionType.CHAT, project)
val contentPanel = ChatCodingPanel(chatCodingService, toolWindow.disposable)
val content =
ContentFactory.getInstance()
.createContent(contentPanel, AutoDevBundle.message("autodev.chat"), false)
val content = ContentFactory.getInstance().createContent(contentPanel, "", false).apply {
setInitialDisplayName(this)
}

ApplicationManager.getApplication().invokeLater {
toolWindow.contentManager.addContent(content)
Expand All @@ -38,5 +39,9 @@ class AutoDevToolWindowFactory : ToolWindowFactory, DumbAware {
fun getToolWindow(project: Project): ToolWindow? {
return ToolWindowManager.getInstance(project).getToolWindow(Util.id)
}

fun setInitialDisplayName(content: Content) {
componentStateChanged("autodev.chat", content, 2) { c, d -> c.displayName = d }
}
}
}
9 changes: 2 additions & 7 deletions src/main/kotlin/cc/unitmesh/devti/gui/chat/AutoDevInput.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package cc.unitmesh.devti.gui.chat

import cc.unitmesh.devti.AutoDevBundle
import cc.unitmesh.devti.settings.LanguageChangedCallback.placeholder
import cc.unitmesh.devti.util.parser.Code.Companion.findLanguage
import com.intellij.openapi.Disposable
import com.intellij.openapi.actionSystem.*
Expand Down Expand Up @@ -50,7 +50,7 @@ class AutoDevInput(

init {
isOneLineMode = false
updatePlaceholderText()
placeholder("chat.panel.initial.text", this)
setFontInheritedFromLAF(true)
addSettingsProvider {
it.putUserData(IncrementalFindAction.SEARCH_DISABLED, true)
Expand Down Expand Up @@ -101,11 +101,6 @@ class AutoDevInput(
editorListeners.multicaster.editorAdded((editor as EditorEx))
}

private fun updatePlaceholderText() {
setPlaceholder(AutoDevBundle.message("chat.panel.initial.text"))
repaint()
}

public override fun createEditor(): EditorEx {
val editor = super.createEditor()
editor.setVerticalScrollbarVisible(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import cc.unitmesh.devti.agent.model.CustomAgentState
import cc.unitmesh.devti.llms.tokenizer.Tokenizer
import cc.unitmesh.devti.llms.tokenizer.TokenizerFactory
import cc.unitmesh.devti.settings.AutoDevSettingsState
import com.intellij.ide.IdeTooltip
import com.intellij.ide.IdeTooltipManager
import com.intellij.openapi.Disposable
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.Presentation
Expand All @@ -21,9 +23,12 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.ComboBox
import com.intellij.openapi.ui.ComponentValidator
import com.intellij.openapi.ui.ValidationInfo
import com.intellij.openapi.ui.popup.Balloon.Position
import com.intellij.openapi.util.NlsContexts
import com.intellij.openapi.wm.IdeFocusManager
import com.intellij.openapi.wm.impl.InternalDecorator
import com.intellij.temporary.gui.block.AutoDevCoolBorder
import com.intellij.ui.HintHint
import com.intellij.ui.MutableCollectionComboBoxModel
import com.intellij.ui.SimpleListCellRenderer
import com.intellij.ui.components.JBLabel
Expand All @@ -35,6 +40,7 @@ import com.intellij.util.ui.components.BorderLayoutPanel
import java.awt.CardLayout
import java.awt.Color
import java.awt.Dimension
import java.awt.Point
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import java.util.function.Supplier
Expand Down Expand Up @@ -91,7 +97,6 @@ class AutoDevInputSection(private val project: Project, val disposable: Disposab
DumbAwareAction.create {
object : DumbAwareAction("") {
override fun actionPerformed(e: AnActionEvent) {
showStopButton()
editorListeners.multicaster.onSubmit(this@AutoDevInputSection, AutoDevInputTrigger.Button)
}
}.actionPerformed(it)
Expand Down Expand Up @@ -179,6 +184,19 @@ class AutoDevInputSection(private val project: Project, val disposable: Disposab
stopButton.isEnabled = true
}

fun showTooltip(text: @NlsContexts.Tooltip String) {
showTooltip(input, Position.above, text)
}

fun showTooltip(component: JComponent, position: Position, text: @NlsContexts.Tooltip String) {
val point = Point(component.x, component.y)
val tipComponent = IdeTooltipManager.initPane(
text, HintHint(component, point).setAwtTooltip(true).setPreferredPosition(position), null
)
val tooltip = IdeTooltip(component, point, tipComponent)
IdeTooltipManager.getInstance().show(tooltip, true)
}

fun showSendButton() {
(buttonPanel.layout as? CardLayout)?.show(buttonPanel, "Send")
buttonPanel.isEnabled = true
Expand Down Expand Up @@ -254,6 +272,7 @@ class AutoDevInputSection(private val project: Project, val disposable: Disposab
}

customRag.selectedItem = defaultRag
text = ""
}

fun moveCursorToStart() {
Expand Down
33 changes: 22 additions & 11 deletions src/main/kotlin/cc/unitmesh/devti/gui/chat/ChatCodingPanel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import cc.unitmesh.devti.gui.chat.welcome.WelcomePanel
import cc.unitmesh.devti.provider.ContextPrompter
import cc.unitmesh.devti.provider.devins.LanguagePromptProcessor
import cc.unitmesh.devti.settings.AutoDevSettingsState
import cc.unitmesh.devti.settings.LanguageChangedCallback.componentStateChanged
import com.intellij.lang.html.HTMLLanguage
import com.intellij.openapi.Disposable
import com.intellij.openapi.diagnostic.logger
Expand Down Expand Up @@ -63,8 +64,7 @@ class ChatCodingPanel(private val chatCodingService: ChatCodingService, val disp
}
}

val panel = WelcomePanel()
myList.add(panel)
myList.add(WelcomePanel())

myTitle.foreground = JBColor.namedColor("Label.infoForeground", JBColor(Gray.x80, Gray.x8C))
myTitle.font = JBFont.label()
Expand All @@ -84,24 +84,26 @@ class ChatCodingPanel(private val chatCodingService: ChatCodingService, val disp

val actionLink = panel {
row {
text(AutoDevBundle.message("label.submit.issue"))
text("").apply {
componentStateChanged("label.submit.issue", this.component) { c, d -> c.text = d }
}
}
}

inputSection = AutoDevInputSection(chatCodingService.project, disposable)
inputSection.addListener(object : AutoDevInputListener {
override fun onStop(component: AutoDevInputSection) {
chatCodingService.stop()
inputSection.showSendButton()
hiddenProgressBar()
}

override fun onSubmit(component: AutoDevInputSection, trigger: AutoDevInputTrigger) {
var prompt = component.text
component.text = ""

inputSection.showStopButton()

if (prompt.isEmpty() || prompt == "\n") {
if (prompt.isEmpty() || prompt.isBlank()) {
component.showTooltip(AutoDevBundle.message("chat.input.tips"))
return
}

Expand Down Expand Up @@ -175,12 +177,12 @@ class ChatCodingPanel(private val chatCodingService: ChatCodingService, val disp
myList.remove(myList.componentCount - 1)
}

progressBar.isVisible = true
showProgressBar()

val result = updateMessageInUi(content)

progressBar.isIndeterminate = false
progressBar.isVisible = false
hiddenProgressBar()
updateUI()

return result
Expand All @@ -206,10 +208,11 @@ class ChatCodingPanel(private val chatCodingService: ChatCodingService, val disp
*/
suspend fun updateReplaceableContent(content: Flow<String>, postAction: (text: String) -> Unit) {
myList.remove(myList.componentCount - 1)
showProgressBar()
val text = updateMessageInUi(content)

progressBar.isIndeterminate = false
progressBar.isVisible = false
hiddenProgressBar()
updateUI()

postAction(text)
Expand All @@ -223,7 +226,7 @@ class ChatCodingPanel(private val chatCodingService: ChatCodingService, val disp
var text = ""
content.onCompletion {
logger.info("onCompletion ${it?.message}")
inputSection.showSendButton()
hiddenProgressBar()
}.catch {
it.printStackTrace()
}.collect {
Expand Down Expand Up @@ -258,9 +261,11 @@ class ChatCodingPanel(private val chatCodingService: ChatCodingService, val disp
* Resets the chat session by clearing the current session and updating the UI.
*/
fun resetChatSession() {
chatCodingService.stop()
suggestionPanel.removeAll()
chatCodingService.clearSession()
progressBar.isVisible = false
myList.removeAll()
myList.add(WelcomePanel())
this.hiddenProgressBar()
this.resetAgent()
updateUI()
Expand All @@ -280,6 +285,12 @@ class ChatCodingPanel(private val chatCodingService: ChatCodingService, val disp

fun hiddenProgressBar() {
progressBar.isVisible = false
inputSection.showSendButton()
}

fun showProgressBar() {
progressBar.isVisible = true
inputSection.showStopButton()
}

fun removeLastMessage() {
Expand Down
22 changes: 14 additions & 8 deletions src/main/kotlin/cc/unitmesh/devti/gui/chat/welcome/WelcomePanel.kt
Original file line number Diff line number Diff line change
@@ -1,34 +1,40 @@
package cc.unitmesh.devti.gui.chat.welcome

import cc.unitmesh.devti.AutoDevBundle
import cc.unitmesh.devti.AutoDevIcons
import cc.unitmesh.devti.settings.LanguageChangedCallback.componentStateChanged
import com.intellij.ui.dsl.builder.RightGap
import com.intellij.ui.dsl.builder.panel
import java.awt.BorderLayout
import javax.swing.JPanel

class WelcomePanel: JPanel(BorderLayout()) {
private val welcomeItems: List<WelcomeItem> = listOf(
WelcomeItem(AutoDevBundle.message("settings.welcome.feature.context")),
WelcomeItem(AutoDevBundle.message("settings.welcome.feature.lifecycle")),
WelcomeItem(AutoDevBundle.message("settings.welcome.feature.custom.action")),
WelcomeItem(AutoDevBundle.message("settings.welcome.feature.custom.agent")),
WelcomeItem("settings.welcome.feature.context"),
WelcomeItem("settings.welcome.feature.lifecycle"),
WelcomeItem("settings.welcome.feature.custom.action"),
WelcomeItem("settings.welcome.feature.custom.agent"),
)

init {
val panel = panel {
row {
text(AutoDevBundle.message("settings.welcome.message"))
text("").apply {
componentStateChanged("settings.welcome.message", this.component) { c, d -> c.text = d }
}
}
welcomeItems.forEach {
row {
// icon
icon(AutoDevIcons.AI_COPILOT).gap(RightGap.SMALL)
text(it.text)
text(it.text).apply {
componentStateChanged(it.text, this.component) { c, d -> c.text = d }
}
}
}
row {
text(AutoDevBundle.message("settings.welcome.feature.features"))
text("").apply {
componentStateChanged("settings.welcome.feature.features", this.component) { c, d -> c.text = d }
}
}
}.apply {
border = javax.swing.BorderFactory.createEmptyBorder(20, 20, 20, 20)
Expand Down
10 changes: 5 additions & 5 deletions src/main/kotlin/cc/unitmesh/devti/gui/toolbar/NewChatAction.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package cc.unitmesh.devti.gui.toolbar

import cc.unitmesh.devti.AutoDevBundle
import cc.unitmesh.devti.gui.AutoDevToolWindowFactory
import cc.unitmesh.devti.gui.chat.ChatCodingPanel
import cc.unitmesh.devti.settings.LanguageChangedCallback.componentStateChanged
import com.intellij.openapi.actionSystem.*
import com.intellij.openapi.actionSystem.ex.CustomComponentAction
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.wm.ToolWindowManager
import com.intellij.ui.components.panels.Wrapper
import com.intellij.util.ui.JBInsets
import com.intellij.util.ui.JBUI
Expand All @@ -20,8 +19,7 @@ class NewChatAction : DumbAwareAction(), CustomComponentAction {
override fun actionPerformed(e: AnActionEvent) = Unit

override fun createCustomComponent(presentation: Presentation, place: String): JComponent {
val message = AutoDevBundle.message("chat.panel.new")
val button: JButton = object : JButton(message) {
val button: JButton = object : JButton() {
init {
putClientProperty("ActionToolbar.smallVariant", true)
putClientProperty("customButtonInsets", JBInsets(1, 1, 1, 1).asUIResource())
Expand All @@ -47,12 +45,14 @@ class NewChatAction : DumbAwareAction(), CustomComponentAction {

// change content displayName AutoDevBundle.message("autodev.chat")
contentManager.contents.forEach {
it.displayName = AutoDevBundle.message("autodev.chat")
AutoDevToolWindowFactory.setInitialDisplayName(it)
}

codingPanel.resetChatSession()
}
}
}.apply {
componentStateChanged("chat.panel.new", this) { b, d -> b.text = d }
}

return Wrapper(button).also {
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/messages/AutoDevBundle_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ chat.panel.new=New Chat
chat.panel.replaceSelection=Replace Selection
chat.panel.initial.text='Enter' to start, 'Shift+Enter' for a new line
chat.too.long.user.message=Message has is {0} tokens too looooooooooooooooooong
chat.input.tips=Content cannot be blank

intention.category.llm=AutoDev
intentions.write.action=Generate code
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/messages/AutoDevBundle_zh.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ chat.panel.new=新建聊天
chat.panel.replaceSelection=替换选择的代码
chat.panel.initial.text='Enter' 发送,'Shift+Enter' 开启新行
chat.too.long.user.message=消息长度太长,包含{0}个 Token
chat.input.tips=内容不能为空

intention.category.llm=AutoDev
intentions.write.action=生成代码
Expand Down
Loading