refactor: archive GUI clients; keep minimal TUI with hooks/API
Move Qt/Tauri/full Web SPA under archive/, ship hermit as CLI/TUI plus libcstcore and cst-webui/1 HTTP+SSE (turn lifecycle hooks, capabilities). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
// One stored session in the sidebar: its name (a rename, else its first
|
||||
// prompt), how much is in it and when it was last written, and a way to drop
|
||||
// it. The open one is marked. A file of its own because the sidebar lists them
|
||||
// through a Repeater -- an inline component would not see modelData there.
|
||||
Rectangle {
|
||||
id: srow
|
||||
property var entry: null
|
||||
readonly property bool open: entry !== null && entry.current === true
|
||||
|
||||
objectName: "sessionRow:" + (entry !== null ? entry.id : "")
|
||||
implicitHeight: rowCol.implicitHeight + 8
|
||||
radius: Theme.radiusSm
|
||||
color: srow.open ? Theme.accentDim
|
||||
: rowHover.hovered ? Theme.surfaceAlt : "transparent"
|
||||
border.width: 1
|
||||
border.color: srow.open ? Theme.accent : "transparent"
|
||||
|
||||
signal activated(string id)
|
||||
signal removeRequested(string id)
|
||||
|
||||
// "3h ago"; the entries carry ms since the epoch.
|
||||
function ago(ms) {
|
||||
if (!ms)
|
||||
return "never"
|
||||
const s = Math.max(0, (Date.now() - ms) / 1000)
|
||||
if (s < 60)
|
||||
return "just now"
|
||||
if (s < 3600)
|
||||
return Math.floor(s / 60) + "m ago"
|
||||
if (s < 86400)
|
||||
return Math.floor(s / 3600) + "h ago"
|
||||
return Math.floor(s / 86400) + "d ago"
|
||||
}
|
||||
|
||||
HoverHandler { id: rowHover }
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: srow.activated(srow.entry.id)
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
margins: 4
|
||||
}
|
||||
spacing: 2
|
||||
|
||||
ColumnLayout {
|
||||
id: rowCol
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 4
|
||||
spacing: 0
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
text: srow.entry !== null && srow.entry.title.length ? srow.entry.title
|
||||
: srow.entry !== null && srow.entry.firstUser.length ? srow.entry.firstUser
|
||||
: "(no prompt yet)"
|
||||
color: srow.open ? Theme.accentText : Theme.textDim
|
||||
font.pixelSize: Theme.smallSize
|
||||
}
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
text: {
|
||||
if (srow.entry === null)
|
||||
return ""
|
||||
const n = srow.entry.messages
|
||||
const when = srow.ago(srow.entry.mtime)
|
||||
return n > 0 ? n + (n === 1 ? " message · " : " messages · ") + when
|
||||
: when
|
||||
}
|
||||
color: srow.open ? Theme.accentTextDim : Theme.textFaint
|
||||
font.pixelSize: Theme.smallSize
|
||||
}
|
||||
}
|
||||
|
||||
ToolButton {
|
||||
objectName: "sessionDelete:" + (srow.entry !== null ? srow.entry.id : "")
|
||||
implicitWidth: 26
|
||||
implicitHeight: 26
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.text: "Delete this session and its transcript"
|
||||
contentItem: ThemeIcon {
|
||||
name: "edit-delete"
|
||||
glyph: "×"
|
||||
size: 14
|
||||
color: parent.hovered ? Theme.err
|
||||
: srow.open ? Theme.accentTextDim : Theme.textFaint
|
||||
}
|
||||
background: Rectangle {
|
||||
radius: Theme.radiusSm
|
||||
color: parent.hovered ? Theme.surfaceHi : "transparent"
|
||||
}
|
||||
onClicked: srow.removeRequested(srow.entry.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user