11package cc.unitmesh.devti.gui.chat
22
33
4- import cc.unitmesh.devti.gui.component.DisplayComponent
54import com.intellij.openapi.actionSystem.DataProvider
65import com.intellij.openapi.actionSystem.ex.ActionUtil
76import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl
@@ -23,9 +22,9 @@ import kotlin.jvm.internal.Ref
2322class MessageView (val message : String , val role : ChatRole , private val displayText : String ) :
2423 JBPanel <MessageView >(), DataProvider {
2524 private val myNameLabel: Component
26- private val component: DisplayComponent = DisplayComponent (message)
2725 private var centerPanel: JPanel = JPanel (VerticalLayout (JBUI .scale(8 )))
2826 private var messageView: SimpleMessage ? = null
27+ private var blocks: MutableList <MessageBlock > = ArrayList ()
2928
3029 init {
3130 isDoubleBuffered = true
@@ -55,17 +54,10 @@ class MessageView(val message: String, val role: ChatRole, private val displayTe
5554 centerPanel.add(myNameLabel)
5655 add(centerPanel, BorderLayout .CENTER )
5756
58- if (role == ChatRole .User ) {
59- ApplicationManager .getApplication().invokeLater {
60- val simpleMessage = SimpleMessage (displayText, message, role)
61- messageView = simpleMessage
62- renderInPartView(simpleMessage)
63- }
64- } else {
65- component.updateMessage(message)
66- component.revalidate()
67- component.repaint()
68- centerPanel.add(component)
57+ ApplicationManager .getApplication().invokeLater {
58+ val simpleMessage = SimpleMessage (displayText, message, role)
59+ messageView = simpleMessage
60+ renderInPartView(simpleMessage)
6961 }
7062 }
7163
@@ -89,25 +81,58 @@ class MessageView(val message: String, val role: ChatRole, private val displayTe
8981 }
9082
9183 private fun renderInPartView (message : SimpleMessage ) {
92- val parts = layoutAll(message)
93- parts.forEach {
94- val blockView = when (it) {
95- is CodeBlock -> {
96- val project = ProjectManager .getInstance().openProjects.firstOrNull()
97- CodeBlockView (it, project!! ) { }
84+ val incrBlocks = layoutAll(message)
85+ if (incrBlocks.isEmpty()) {
86+ return
87+ }
88+ if (this .blocks.isEmpty()) {
89+ blocks.addAll(incrBlocks)
90+ } else {
91+ var newBlock: MessageBlock
92+ var i = 0
93+ while (i < minOf(this .blocks.size, incrBlocks.size)) {
94+ val oldBlock = this .blocks[i]
95+ newBlock = incrBlocks[i]
96+ if (oldBlock.getIdentifier() == newBlock.getIdentifier()) { // 如果新旧内容一样忽略
97+ i++
98+ continue
9899 }
99-
100- else -> TextBlockView (it)
100+ oldBlock.setNeedUpdate(true )
101+ oldBlock.addContent(newBlock.getTextContent())
102+ i++
101103 }
104+ for (j in i until incrBlocks.size) {
105+ newBlock = incrBlocks[j]
106+ newBlock.setNeedUpdate(true )
107+ this .blocks.add(newBlock) // 添加到 blocks
108+ }
109+ }
110+ renderComponent();
111+ }
102112
103- blockView.initialize()
104- val component = blockView.getComponent() ? : return @forEach
113+ private fun renderComponent (){
114+ blocks.forEach { block ->
115+ if (! block.isNeedUpdate()) return @forEach
105116
106- component.setForeground(JBUI .CurrentTheme .Label .foreground())
107- centerPanel.add(component)
117+ if (block.getMessageBlockView() == null ) {
118+ val blockView = when (block) {
119+ is CodeBlock -> {
120+ val project = ProjectManager .getInstance().openProjects.first()
121+ CodeBlockView (block, project) { }
122+ }
123+ else -> TextBlockView (block)
124+ }
125+ blockView.initialize()
126+ block.setMessageBlockView(blockView)
127+
128+ val component = blockView.getComponent() ? : return @forEach
129+ component.setForeground(JBUI .CurrentTheme .Label .foreground())
130+ centerPanel.add(component)
131+ }
132+ block.setNeedUpdate(false )
108133 }
109- }
110134
135+ }
111136 private var answer: String = " "
112137
113138 fun updateContent (content : String ) {
@@ -124,7 +149,7 @@ class MessageView(val message: String, val role: ChatRole, private val displayTe
124149
125150 fun reRenderAssistantOutput () {
126151 ApplicationManager .getApplication().invokeLater {
127- centerPanel.remove(component)
152+
128153 centerPanel.updateUI()
129154
130155 centerPanel.add(myNameLabel)
@@ -148,8 +173,8 @@ class MessageView(val message: String, val role: ChatRole, private val displayTe
148173 override fun done () {
149174 try {
150175 get()
151- component.updateMessage (message)
152- component.updateUI( )
176+ val simpleMessage = SimpleMessage (message, this @MessageView.message, role )
177+ renderInPartView(simpleMessage )
153178 } catch (e: Exception ) {
154179 logger.error(message, e.message)
155180 }
@@ -246,7 +271,7 @@ class MessageView(val message: String, val role: ChatRole, private val displayTe
246271
247272 override fun getData (dataId : String ): CompletableMessage ? {
248273 return if (CompletableMessage .key.`is `(dataId)) {
249- return this .messageView
274+ return this .messageView
250275 } else {
251276 null
252277 }
0 commit comments