mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
fix(jetbrains): address history review gaps
This commit is contained in:
+5
-8
@@ -18,7 +18,7 @@ class HistoryController(
|
||||
private val deleted: (String) -> Unit = {},
|
||||
) {
|
||||
companion object {
|
||||
const val CLOUD_LIMIT = 150
|
||||
const val CLOUD_LIMIT = 50
|
||||
}
|
||||
|
||||
val local = HistoryModel<LocalHistoryItem>()
|
||||
@@ -26,11 +26,10 @@ class HistoryController(
|
||||
|
||||
private val deleting = mutableSetOf<String>()
|
||||
private val opener = open
|
||||
private var git: String? = null
|
||||
|
||||
fun reload(gitUrl: String? = null) {
|
||||
fun reload() {
|
||||
reloadLocal()
|
||||
reloadCloud(gitUrl)
|
||||
reloadCloud()
|
||||
}
|
||||
|
||||
fun reloadLocal() {
|
||||
@@ -46,8 +45,7 @@ class HistoryController(
|
||||
}
|
||||
}
|
||||
|
||||
fun reloadCloud(gitUrl: String? = null) {
|
||||
git = gitUrl
|
||||
fun reloadCloud() {
|
||||
loadCloud(reset = true)
|
||||
}
|
||||
|
||||
@@ -104,11 +102,10 @@ class HistoryController(
|
||||
|
||||
private fun loadCloud(reset: Boolean) {
|
||||
val cursor = cloud.cursor.takeUnless { reset }
|
||||
val gitUrl = git
|
||||
edt { cloud.start(reset) }
|
||||
cs.launch {
|
||||
try {
|
||||
val result = sessions.cloudSessions(workspace.directory, cursor, CLOUD_LIMIT, gitUrl)
|
||||
val result = sessions.cloudSessions(workspace.directory, cursor, CLOUD_LIMIT, null)
|
||||
val items = result.sessions.map(::cloudItem)
|
||||
edt {
|
||||
if (reset) cloud.replace(items, result.nextCursor)
|
||||
|
||||
-2
@@ -66,8 +66,6 @@ open class HistoryModel<T : HistoryItem> : AbstractListModel<T>() {
|
||||
filter()
|
||||
}
|
||||
|
||||
fun hasFilter(): Boolean = query.isNotEmpty()
|
||||
|
||||
fun refresh() {
|
||||
val end = size.coerceAtLeast(1) - 1
|
||||
fireContentsChanged(this, 0, end)
|
||||
|
||||
+20
-13
@@ -7,13 +7,16 @@ import ai.kilocode.client.session.ui.style.SessionEditorStyle
|
||||
import ai.kilocode.client.ui.UiStyle
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.ide.ui.LafManagerListener
|
||||
import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.actionSystem.ActionGroup
|
||||
import com.intellij.openapi.actionSystem.ActionManager
|
||||
import com.intellij.openapi.actionSystem.ActionPlaces
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.DataProvider
|
||||
import com.intellij.openapi.actionSystem.Presentation
|
||||
import com.intellij.openapi.actionSystem.impl.ActionButton
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.ui.DocumentAdapter
|
||||
import com.intellij.ui.PopupHandler
|
||||
@@ -53,7 +56,6 @@ import javax.swing.event.ListDataListener
|
||||
class HistoryPanel(
|
||||
parent: Disposable,
|
||||
private val controller: HistoryController,
|
||||
private val gitUrl: () -> String? = { null },
|
||||
private val nav: () -> Unit = {},
|
||||
private val manager: SessionManager? = null,
|
||||
) : BorderLayoutPanel(), Disposable, DataProvider {
|
||||
@@ -116,7 +118,7 @@ class HistoryPanel(
|
||||
fun refresh() {
|
||||
stale = false
|
||||
updateTheme()
|
||||
controller.reload(gitUrl())
|
||||
controller.reload()
|
||||
}
|
||||
|
||||
private fun bindTheme() {
|
||||
@@ -167,14 +169,19 @@ class HistoryPanel(
|
||||
)
|
||||
}
|
||||
|
||||
private fun back() = BorderLayoutPanel().apply {
|
||||
add(JButton(KiloBundle.message("history.back"), AllIcons.Actions.Back).apply {
|
||||
putClientProperty(DarculaButtonUI.DEFAULT_STYLE_KEY, true)
|
||||
isFocusable = false
|
||||
private fun back(): BorderLayoutPanel {
|
||||
val label = KiloBundle.message("history.back")
|
||||
val action = object : AnAction(label, null, AllIcons.Actions.Back) {
|
||||
override fun actionPerformed(e: AnActionEvent) = nav()
|
||||
}
|
||||
val presentation = Presentation(label).apply { icon = AllIcons.Actions.Back }
|
||||
val btn = ActionButton(action, presentation, ActionPlaces.TOOLBAR, JBUI.size(16)).apply {
|
||||
cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)
|
||||
addActionListener { nav() }
|
||||
}, BorderLayout.WEST)
|
||||
border = JBUI.Borders.emptyRight(UiStyle.Gap.lg())
|
||||
}
|
||||
return BorderLayoutPanel().apply {
|
||||
add(btn, BorderLayout.WEST)
|
||||
border = JBUI.Borders.emptyRight(UiStyle.Gap.lg())
|
||||
}
|
||||
}
|
||||
|
||||
private fun panel(search: SearchTextField, list: JList<out HistoryItem>, footer: JComponent? = null): JComponent {
|
||||
@@ -356,17 +363,17 @@ class HistoryPanel(
|
||||
|
||||
internal fun backText(): String? {
|
||||
val view = activeInfo().foreSideComponent ?: return null
|
||||
return UIUtil.uiTraverser(view).filter(JButton::class.java).firstOrNull()?.text
|
||||
return UIUtil.uiTraverser(view).filter(ActionButton::class.java).firstOrNull()?.presentation?.text
|
||||
}
|
||||
|
||||
internal fun backCursor(): Int? {
|
||||
val view = activeInfo().foreSideComponent ?: return null
|
||||
return UIUtil.uiTraverser(view).filter(JButton::class.java).firstOrNull()?.cursor?.type
|
||||
return UIUtil.uiTraverser(view).filter(ActionButton::class.java).firstOrNull()?.cursor?.type
|
||||
}
|
||||
|
||||
internal fun clickBack() {
|
||||
val view = activeInfo().foreSideComponent ?: return
|
||||
UIUtil.uiTraverser(view).filter(JButton::class.java).firstOrNull()?.doClick()
|
||||
UIUtil.uiTraverser(view).filter(ActionButton::class.java).firstOrNull()?.click()
|
||||
}
|
||||
|
||||
internal fun clickDelete() {
|
||||
|
||||
+2
-2
@@ -35,8 +35,8 @@ internal object HistoryTime {
|
||||
val today = Instant.ofEpochMilli(now).atZone(zone).toLocalDate()
|
||||
if (date == today) return HistorySection.TODAY
|
||||
if (date == today.minusDays(1)) return HistorySection.YESTERDAY
|
||||
if (date.isAfter(today.minusDays(7)) && date.isBefore(today)) return HistorySection.WEEK
|
||||
if (date.isAfter(today.minusDays(30)) && date.isBefore(today)) return HistorySection.MONTH
|
||||
if (!date.isBefore(today.minusDays(7)) && date.isBefore(today)) return HistorySection.WEEK
|
||||
if (!date.isBefore(today.minusDays(30)) && date.isBefore(today)) return HistorySection.MONTH
|
||||
return HistorySection.OLDER
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,6 @@ history.delete.confirm.message.multiple=Delete {0} sessions from local history?
|
||||
history.rename.title=Rename Session
|
||||
history.rename.prompt=New session name:
|
||||
history.cloud.load.more=Load more
|
||||
history.cloud.repo.only=Only this repository
|
||||
history.group.today=Today
|
||||
history.group.yesterday=Yesterday
|
||||
history.group.week=This Week
|
||||
|
||||
+18
-3
@@ -81,13 +81,13 @@ class HistoryControllerTest : BasePlatformTestCase() {
|
||||
rpc.cloudCursor = "next_1"
|
||||
val controller = controller()
|
||||
|
||||
controller.reloadCloud(gitUrl = "git@example.com:repo.git")
|
||||
controller.reloadCloud()
|
||||
flush()
|
||||
|
||||
assertEquals(1, controller.cloud.items.size)
|
||||
assertEquals("cloud_1", controller.cloud.items[0].id)
|
||||
assertEquals("next_1", controller.cloud.cursor)
|
||||
assertEquals(FakeSessionRpcApi.CloudCall("/test", null, 150, "git@example.com:repo.git"), rpc.cloudCalls[0])
|
||||
assertEquals(FakeSessionRpcApi.CloudCall("/test", null, 50, null), rpc.cloudCalls[0])
|
||||
|
||||
rpc.cloud.clear()
|
||||
rpc.cloud += cloud("cloud_2", "Cloud Two")
|
||||
@@ -96,7 +96,7 @@ class HistoryControllerTest : BasePlatformTestCase() {
|
||||
flush()
|
||||
|
||||
assertEquals(listOf("cloud_1", "cloud_2"), controller.cloud.items.map { it.id })
|
||||
assertEquals(FakeSessionRpcApi.CloudCall("/test", "next_1", 150, "git@example.com:repo.git"), rpc.cloudCalls[1])
|
||||
assertEquals(FakeSessionRpcApi.CloudCall("/test", "next_1", 50, null), rpc.cloudCalls[1])
|
||||
}
|
||||
|
||||
fun `test local delete calls rpc and removes item`() {
|
||||
@@ -298,6 +298,21 @@ class HistoryControllerTest : BasePlatformTestCase() {
|
||||
assertEquals(KiloBundle.message("history.time.hours", 10), HistoryTime.relative(offset, now.toEpochMilli()))
|
||||
}
|
||||
|
||||
fun `test history section boundaries are inclusive at 7 and 30 days`() {
|
||||
val now = Instant.now()
|
||||
val exactly7 = LocalHistoryItem(session("s7", "7d", now.minus(7, ChronoUnit.DAYS).toEpochMilli().toDouble()))
|
||||
val exactly30 = LocalHistoryItem(session("s30", "30d", now.minus(30, ChronoUnit.DAYS).toEpochMilli().toDouble()))
|
||||
val within7 = LocalHistoryItem(session("s6", "6d", now.minus(6, ChronoUnit.DAYS).toEpochMilli().toDouble()))
|
||||
val within30 = LocalHistoryItem(session("s29", "29d", now.minus(29, ChronoUnit.DAYS).toEpochMilli().toDouble()))
|
||||
val beyond30 = LocalHistoryItem(session("s31", "31d", now.minus(31, ChronoUnit.DAYS).toEpochMilli().toDouble()))
|
||||
|
||||
assertEquals(HistorySection.WEEK, HistoryTime.section(exactly7, now.toEpochMilli()))
|
||||
assertEquals(HistorySection.WEEK, HistoryTime.section(within7, now.toEpochMilli()))
|
||||
assertEquals(HistorySection.MONTH, HistoryTime.section(exactly30, now.toEpochMilli()))
|
||||
assertEquals(HistorySection.MONTH, HistoryTime.section(within30, now.toEpochMilli()))
|
||||
assertEquals(HistorySection.OLDER, HistoryTime.section(beyond30, now.toEpochMilli()))
|
||||
}
|
||||
|
||||
fun `test list is focusable and uses multiple interval selection`() {
|
||||
val panel = HistoryPanel(parent, controller())
|
||||
flush()
|
||||
|
||||
Reference in New Issue
Block a user