diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryController.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryController.kt index a416a684642..d66e4665ecb 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryController.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryController.kt @@ -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() @@ -26,11 +26,10 @@ class HistoryController( private val deleting = mutableSetOf() 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) diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryModel.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryModel.kt index ec457e8a5a1..67b6c105e93 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryModel.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryModel.kt @@ -66,8 +66,6 @@ open class HistoryModel : AbstractListModel() { filter() } - fun hasFilter(): Boolean = query.isNotEmpty() - fun refresh() { val end = size.coerceAtLeast(1) - 1 fireContentsChanged(this, 0, end) diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryPanel.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryPanel.kt index c27bc0a7524..1cdefe26bb0 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryPanel.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryPanel.kt @@ -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, 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() { diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryTime.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryTime.kt index 1b3f9516ecf..a498e09365d 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryTime.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/history/HistoryTime.kt @@ -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 } diff --git a/packages/kilo-jetbrains/frontend/src/main/resources/messages/KiloBundle.properties b/packages/kilo-jetbrains/frontend/src/main/resources/messages/KiloBundle.properties index 298028014b7..aeee59d987c 100644 --- a/packages/kilo-jetbrains/frontend/src/main/resources/messages/KiloBundle.properties +++ b/packages/kilo-jetbrains/frontend/src/main/resources/messages/KiloBundle.properties @@ -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 diff --git a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/history/HistoryControllerTest.kt b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/history/HistoryControllerTest.kt index 213f6cd7440..8cddf763f0a 100644 --- a/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/history/HistoryControllerTest.kt +++ b/packages/kilo-jetbrains/frontend/src/test/kotlin/ai/kilocode/client/session/history/HistoryControllerTest.kt @@ -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()