mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-10-30 19:32:39 +08:00
fix(jetbrains): increase user prompt transcript gap
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@kilocode/kilo-jetbrains": patch
|
||||
---
|
||||
|
||||
Increase spacing before non-initial user prompts in the JetBrains session transcript.
|
||||
+10
-3
@@ -44,7 +44,7 @@ class SessionLayout(
|
||||
var first = true
|
||||
for (comp in parent.components) {
|
||||
if (!comp.isVisible) continue
|
||||
if (!first) h += gap
|
||||
if (!first) h += gap(comp)
|
||||
first = false
|
||||
val child = bounds(ins, w, comp)
|
||||
// Pre-size to available width so HTML panes reflow before we measure
|
||||
@@ -63,7 +63,7 @@ class SessionLayout(
|
||||
var first = true
|
||||
for (comp in parent.components) {
|
||||
if (!comp.isVisible) continue
|
||||
if (!first) y += gap
|
||||
if (!first) y += gap(comp)
|
||||
first = false
|
||||
val child = bounds(ins, w, comp)
|
||||
// Fix width first so HTML reflows, then read the resulting height
|
||||
@@ -75,7 +75,7 @@ class SessionLayout(
|
||||
}
|
||||
|
||||
private fun bounds(ins: Insets, width: Int, comp: Component): Bounds {
|
||||
val view = comp as? SessionView ?: return Bounds(ins.left, width)
|
||||
val view = view(comp) ?: return Bounds(ins.left, width)
|
||||
if (view.sessionViewKind != SessionView.Kind.UserPrompt) return Bounds(ins.left, width)
|
||||
val shift = JBUI.scale(SessionUiStyle.SessionLayout.USER_PROMPT_INDENT)
|
||||
val next = width - shift
|
||||
@@ -93,6 +93,13 @@ class SessionLayout(
|
||||
)
|
||||
}
|
||||
|
||||
private fun gap(comp: Component): Int {
|
||||
if (view(comp)?.sessionGapKind == SessionView.Kind.UserPrompt) return JBUI.scale(SessionUiStyle.SessionLayout.USER_PROMPT_GAP)
|
||||
return gap
|
||||
}
|
||||
|
||||
private fun view(comp: Component): SessionView? = comp as? SessionView
|
||||
|
||||
private data class Bounds(val left: Int, val width: Int)
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -2,6 +2,7 @@ package ai.kilocode.client.session.ui
|
||||
|
||||
interface SessionView {
|
||||
val sessionViewKind: Kind
|
||||
val sessionGapKind: Kind get() = sessionViewKind
|
||||
|
||||
enum class Kind {
|
||||
Default,
|
||||
|
||||
+1
@@ -16,6 +16,7 @@ object SessionUiStyle {
|
||||
/** Geometry for the transcript list and its scroll behavior. */
|
||||
object SessionLayout {
|
||||
const val GAP = 3
|
||||
const val USER_PROMPT_GAP = 10
|
||||
const val TRANSCRIPT_SCROLLBAR_PADDING = 10
|
||||
val InnerInsets = Insets(
|
||||
UiStyle.Gap.md(),
|
||||
|
||||
+7
-1
@@ -4,6 +4,7 @@ import ai.kilocode.client.session.SessionFileOpener
|
||||
import ai.kilocode.client.session.model.FileAttachment
|
||||
import ai.kilocode.client.session.model.Message
|
||||
import ai.kilocode.client.session.ui.SessionLayoutPanel
|
||||
import ai.kilocode.client.session.ui.SessionView
|
||||
import ai.kilocode.client.session.ui.style.SessionEditorStyle
|
||||
import ai.kilocode.client.session.ui.selection.SessionSelection
|
||||
import ai.kilocode.client.session.ui.style.SessionEditorStyleTarget
|
||||
@@ -35,10 +36,15 @@ class TurnView(
|
||||
private val repo: String? = null,
|
||||
private val hover: ((PartView, Boolean) -> Unit)? = null,
|
||||
private val revert: ((String) -> Unit)? = null,
|
||||
) : SessionLayoutPanel(JBUI.scale(SessionUiStyle.SessionLayout.GAP)), Disposable, SessionEditorStyleTarget {
|
||||
) : SessionLayoutPanel(JBUI.scale(SessionUiStyle.SessionLayout.GAP)), Disposable, SessionEditorStyleTarget, SessionView {
|
||||
|
||||
private val messages = LinkedHashMap<String, MessageView>()
|
||||
|
||||
override val sessionViewKind = SessionView.Kind.Default
|
||||
|
||||
override val sessionGapKind: SessionView.Kind
|
||||
get() = messages.values.firstOrNull { it.isVisible }?.sessionViewKind ?: SessionView.Kind.Default
|
||||
|
||||
init {
|
||||
isOpaque = false
|
||||
}
|
||||
|
||||
+26
@@ -11,10 +11,12 @@ import ai.kilocode.client.session.ui.ConnectionPanel
|
||||
import ai.kilocode.client.session.ui.empty.EmptySessionPanel
|
||||
import ai.kilocode.client.session.ui.LoadingPanel
|
||||
import ai.kilocode.client.session.ui.SessionDropOverlay
|
||||
import ai.kilocode.client.session.ui.SessionLayoutPanel
|
||||
import ai.kilocode.client.session.ui.prompt.PromptPanel
|
||||
import ai.kilocode.client.session.ui.account.SessionAccountOverlay
|
||||
import ai.kilocode.client.session.ui.SessionMessageListPanel
|
||||
import ai.kilocode.client.session.ui.SessionRootPanel
|
||||
import ai.kilocode.client.session.ui.SessionView
|
||||
import ai.kilocode.client.session.ui.style.SessionEditorStyle
|
||||
import ai.kilocode.client.session.ui.header.SessionHeaderPanel
|
||||
import ai.kilocode.client.session.ui.style.SessionUiStyle
|
||||
@@ -29,7 +31,9 @@ import ai.kilocode.client.session.views.permission.PermissionView
|
||||
import ai.kilocode.client.session.views.question.QuestionView
|
||||
import ai.kilocode.rpc.dto.MessageWithPartsDto
|
||||
import com.intellij.ui.components.JBScrollPane
|
||||
import java.awt.Dimension
|
||||
import javax.swing.JLayeredPane
|
||||
import javax.swing.JPanel
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
class SessionUiLayoutTest : SessionUiTestBase() {
|
||||
@@ -73,6 +77,24 @@ class SessionUiLayoutTest : SessionUiTestBase() {
|
||||
assertFalse(root.content.components.contains(connection))
|
||||
}
|
||||
|
||||
fun `test transcript uses larger standard gap before prompts after first item`() {
|
||||
val panel = SessionLayoutPanel(gap = SessionUiStyle.SessionLayout.GAP).apply {
|
||||
setSize(400, 300)
|
||||
add(Row(SessionView.Kind.UserPrompt))
|
||||
add(Row(SessionView.Kind.Default))
|
||||
add(Row(SessionView.Kind.UserPrompt))
|
||||
}
|
||||
|
||||
panel.doLayout()
|
||||
|
||||
assertEquals(0, panel.getComponent(0).y)
|
||||
assertEquals(SessionUiStyle.SessionLayout.GAP, panel.getComponent(1).y - panel.getComponent(0).bounds.maxY.toInt())
|
||||
assertEquals(
|
||||
JBUI.scale(SessionUiStyle.SessionLayout.USER_PROMPT_GAP),
|
||||
panel.getComponent(2).y - panel.getComponent(1).bounds.maxY.toInt(),
|
||||
)
|
||||
}
|
||||
|
||||
fun `test drop overlay is attached under root overlay layer`() {
|
||||
val root = find<SessionRootPanel>(ui)
|
||||
val drop = find<SessionDropOverlay>(ui)
|
||||
@@ -640,4 +662,8 @@ class SessionUiLayoutTest : SessionUiTestBase() {
|
||||
.components
|
||||
.single()
|
||||
.let { it as javax.swing.JComponent }
|
||||
|
||||
private class Row(override val sessionViewKind: SessionView.Kind) : JPanel(), SessionView {
|
||||
override fun getPreferredSize() = Dimension(100, 10)
|
||||
}
|
||||
}
|
||||
|
||||
+34
@@ -1,5 +1,6 @@
|
||||
package ai.kilocode.client.session.ui
|
||||
|
||||
import ai.kilocode.client.session.ui.style.SessionUiStyle
|
||||
import com.intellij.testFramework.fixtures.BasePlatformTestCase
|
||||
import com.intellij.util.ui.JBUI
|
||||
import com.intellij.util.ui.components.BorderLayoutPanel
|
||||
@@ -68,6 +69,29 @@ class SessionLayoutTest : BasePlatformTestCase() {
|
||||
assertEquals(33, c3.y) // 10 + 4 + 15 + 4
|
||||
}
|
||||
|
||||
fun `test user prompt after first component uses prompt gap`() {
|
||||
val p = panel(gap = 4, width = 300)
|
||||
val c1 = label(height = 20)
|
||||
val c2 = view(height = 30, kind = SessionView.Kind.UserPrompt)
|
||||
p.add(c1)
|
||||
p.add(c2)
|
||||
p.doLayout()
|
||||
|
||||
assertEquals(20 + JBUI.scale(SessionUiStyle.SessionLayout.USER_PROMPT_GAP), c2.y)
|
||||
}
|
||||
|
||||
fun `test first user prompt uses standard gap`() {
|
||||
val p = panel(gap = 4, width = 300)
|
||||
val c1 = view(height = 20, kind = SessionView.Kind.UserPrompt)
|
||||
val c2 = label(height = 30)
|
||||
p.add(c1)
|
||||
p.add(c2)
|
||||
p.doLayout()
|
||||
|
||||
assertEquals(0, c1.y)
|
||||
assertEquals(20 + 4, c2.y)
|
||||
}
|
||||
|
||||
fun `test all children receive full available width`() {
|
||||
val p = panel(width = 500)
|
||||
val c1 = label(height = 20)
|
||||
@@ -199,6 +223,16 @@ class SessionLayoutTest : BasePlatformTestCase() {
|
||||
assertEquals(10 + 4 + 15 + 4 + 20, size.height)
|
||||
}
|
||||
|
||||
fun `test preferredLayoutSize uses prompt gap before non-first user prompt`() {
|
||||
val p = panel(gap = 4, width = 300)
|
||||
p.add(label(height = 10))
|
||||
p.add(view(height = 15, kind = SessionView.Kind.UserPrompt))
|
||||
p.doLayout()
|
||||
|
||||
val size = p.layout.preferredLayoutSize(p)
|
||||
assertEquals(10 + JBUI.scale(SessionUiStyle.SessionLayout.USER_PROMPT_GAP) + 15, size.height)
|
||||
}
|
||||
|
||||
fun `test preferredLayoutSize with no children is zero`() {
|
||||
val p = panel(width = 300)
|
||||
val size = p.layout.preferredLayoutSize(p)
|
||||
|
||||
+20
@@ -42,6 +42,7 @@ import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.testFramework.fixtures.BasePlatformTestCase
|
||||
import com.intellij.ui.components.JBLabel
|
||||
import com.intellij.ui.components.JBScrollPane
|
||||
import com.intellij.util.ui.JBUI
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Color
|
||||
@@ -105,6 +106,25 @@ class SessionMessageListPanelTest : BasePlatformTestCase() {
|
||||
assertEquals(right, left)
|
||||
}
|
||||
|
||||
fun `test top level user turns use prompt gap after previous turn`() {
|
||||
model.upsertMessage(msg("u1", "user"))
|
||||
model.updateContent("u1", part("p1", "u1", "text", text = "first"))
|
||||
model.upsertMessage(msg("a1", "assistant"))
|
||||
model.updateContent("a1", part("p2", "a1", "text", text = "answer"))
|
||||
model.upsertMessage(msg("u2", "user"))
|
||||
model.updateContent("u2", part("p3", "u2", "text", text = "second"))
|
||||
|
||||
panel.setSize(600, 1000)
|
||||
layout(panel)
|
||||
val first = panel.findTurn("u1")!!
|
||||
val second = panel.findTurn("u2")!!
|
||||
|
||||
assertEquals(
|
||||
JBUI.scale(SessionUiStyle.SessionLayout.USER_PROMPT_GAP),
|
||||
second.y - first.bounds.maxY.toInt(),
|
||||
)
|
||||
}
|
||||
|
||||
// ------ TurnAdded ------
|
||||
|
||||
fun `test user message creates turn and is findable by message id`() {
|
||||
|
||||
Reference in New Issue
Block a user