gui: fix session tree view delegate crashes and scrollable input
- Guard delegate against undefined properties during initial render - Use || 0 fallbacks for optional model properties - Remove broken ScrollBar.vertical.value assignment (not assignable) - Fix Keys.onReturnPressed to use explicit function(event) parameter - Call buildSessionTree() on Component.onCompleted
This commit is contained in:
parent
3cedf602be
commit
69458631dc
81
gui/main.qml
81
gui/main.qml
|
|
@ -73,11 +73,13 @@ ApplicationWindow {
|
|||
}
|
||||
|
||||
function buildSessionTree() {
|
||||
console.log("buildSessionTree: sessions count = " + ollie.sessions.length)
|
||||
sessionTreeModel.clear()
|
||||
var sessions = ollie.sessions
|
||||
for (var i = 0; i < sessions.length; ++i) {
|
||||
var sess = sessions[i].toMap()
|
||||
var sess = sessions[i]
|
||||
var sid = sess.id || ""
|
||||
console.log(" session[" + i + "] = " + sid)
|
||||
// Auto-expand active session
|
||||
var expanded = (sid === ollie.activeSessionId)
|
||||
// Add session node
|
||||
|
|
@ -91,19 +93,25 @@ ApplicationWindow {
|
|||
displayName: sid
|
||||
})
|
||||
// Fetch agents and add them
|
||||
var agents = ollie.getAgents(sid)
|
||||
for (var j = 0; j < agents.length; ++j) {
|
||||
var aid = agents[j]
|
||||
sessionTreeModel.append({
|
||||
type: "agent",
|
||||
parentId: sid,
|
||||
agentId: aid,
|
||||
level: 1,
|
||||
state: "idle",
|
||||
displayName: "Agent " + aid
|
||||
})
|
||||
try {
|
||||
var agents = ollie.getAgents(sid)
|
||||
console.log(" agents for " + sid + ": " + agents.length)
|
||||
for (var j = 0; j < agents.length; ++j) {
|
||||
var aid = agents[j]
|
||||
sessionTreeModel.append({
|
||||
type: "agent",
|
||||
parentId: sid,
|
||||
agentId: aid,
|
||||
level: 1,
|
||||
state: "idle",
|
||||
displayName: "Agent " + aid
|
||||
})
|
||||
}
|
||||
} catch(e) {
|
||||
console.log(" error getting agents for " + sid + ": " + e)
|
||||
}
|
||||
}
|
||||
console.log(" total tree items: " + sessionTreeModel.count)
|
||||
}
|
||||
|
||||
function toggleExpand(index) {
|
||||
|
|
@ -131,6 +139,7 @@ ApplicationWindow {
|
|||
chatModel.trimFront(30)
|
||||
}
|
||||
scrollTimer.start()
|
||||
buildSessionTree()
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
|
@ -305,54 +314,47 @@ ApplicationWindow {
|
|||
|
||||
delegate: ItemDelegate {
|
||||
width: sessionList.width
|
||||
|
||||
// Guard against undefined during initial render
|
||||
height: {
|
||||
if (modelData.type === "agent" && !parentSessionExpanded(modelData.parentId))
|
||||
if (!type) return 0
|
||||
if (type === "agent" && !parentSessionExpanded(parentId))
|
||||
return 0
|
||||
return 28
|
||||
}
|
||||
visible: height > 0
|
||||
|
||||
property var _parentItem: null
|
||||
|
||||
contentItem: RowLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
||||
// Expand/collapse indicator
|
||||
// Indent + expand/collapse indicator
|
||||
Label {
|
||||
Layout.leftPadding: modelData.level * 16 + 4
|
||||
Layout.preferredWidth: 16
|
||||
text: modelData.type === "session" ? (modelData.expanded ? "▼" : "▶") : ""
|
||||
Layout.preferredWidth: (level || 0) * 16 + 16
|
||||
text: type === "session" ? (expanded ? "▼" : "▶") : ""
|
||||
font.pixelSize: theme.fontSize > 0 ? theme.fontSize * 0.7 : 10
|
||||
color: theme.textColor
|
||||
opacity: 0.6
|
||||
}
|
||||
|
||||
// Icon/type indicator
|
||||
Label {
|
||||
Layout.preferredWidth: 16
|
||||
text: modelData.type === "session" ? "📁" : "🤖"
|
||||
font.pixelSize: theme.fontSize > 0 ? theme.fontSize * 0.8 : 11
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
// Name
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: modelData.displayName || ""
|
||||
text: displayName || ""
|
||||
color: theme.textColor
|
||||
font.pointSize: theme.fontSize > 0 ? theme.fontSize : Qt.application.font.pointSize
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
leftPadding: 4
|
||||
}
|
||||
|
||||
// State dot
|
||||
Rectangle {
|
||||
Layout.preferredWidth: 8
|
||||
Layout.preferredHeight: 8
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
radius: 4
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: {
|
||||
var s = modelData.state || "idle"
|
||||
var s = state || "idle"
|
||||
if (s === "idle") return "#4caf50"
|
||||
if (s.startsWith("calling")) return "#ff9800"
|
||||
return "#2196f3"
|
||||
|
|
@ -361,19 +363,19 @@ ApplicationWindow {
|
|||
}
|
||||
|
||||
onClicked: {
|
||||
if (modelData.type === "session") {
|
||||
if (type === "session") {
|
||||
toggleExpand(index)
|
||||
} else if (modelData.type === "agent") {
|
||||
activateAgent(modelData.parentId, modelData.agentId)
|
||||
} else if (type === "agent") {
|
||||
activateAgent(parentId, agentId)
|
||||
}
|
||||
}
|
||||
|
||||
highlighted: (modelData.type === "agent" && modelData.agentId === ollie.activeAgentId && modelData.parentId === ollie.activeSessionId)
|
||||
highlighted: (type === "agent" && agentId === ollie.activeAgentId && parentId === ollie.activeSessionId)
|
||||
|
||||
function parentSessionExpanded(parentId) {
|
||||
function parentSessionExpanded(pid) {
|
||||
for (var i = 0; i < sessionTreeModel.count; ++i) {
|
||||
var item = sessionTreeModel.get(i)
|
||||
if (item.id === parentId && item.type === "session")
|
||||
if (item.id === pid && item.type === "session")
|
||||
return item.expanded
|
||||
}
|
||||
return false
|
||||
|
|
@ -554,6 +556,7 @@ ApplicationWindow {
|
|||
spacing: 4
|
||||
|
||||
ScrollView {
|
||||
id: promptScroll
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumHeight: 200
|
||||
Layout.preferredHeight: Math.min(promptInput.contentHeight + 16, 200)
|
||||
|
|
@ -565,11 +568,7 @@ ApplicationWindow {
|
|||
placeholderText: ollie.activeSessionId ? "Message..." : "No session"
|
||||
enabled: ollie.activeSessionId !== ""
|
||||
wrapMode: TextEdit.Wrap
|
||||
onTextChanged: {
|
||||
// Auto-scroll to bottom as content grows
|
||||
textCursor.position = text.length
|
||||
}
|
||||
Keys.onReturnPressed: {
|
||||
Keys.onReturnPressed: function(event) {
|
||||
if (event.modifiers & Qt.ShiftModifier) {
|
||||
event.accepted = false
|
||||
} else {
|
||||
|
|
|
|||
Reference in New Issue