Files
z-bar-qt/Modules/Notifications/Sidebar/Chat/Content/Reasoning.qml
T

108 lines
2.6 KiB
QML

import QtQuick
import ZShell.Config
import ZShell.Llm
import qs.Components
import qs.Services
Item {
id: root
required property ChatGeneration current
property bool expanded: false
readonly property bool isReasoning: root.current.reasoningActive || root.current.content === ""
implicitHeight: expandedRect.implicitHeight + collapsedText.implicitHeight + expandedRect.anchors.topMargin
LoadingIndicator {
id: spinnerReasoning
anchors.left: parent.left
anchors.margins: Tokens.padding.medium
anchors.verticalCenter: parent.verticalCenter
implicitSize: collapsedText.implicitHeight
opacity: root.isReasoning ? 1 : 0
visible: opacity > 0
Behavior on opacity {
Anim {
}
}
}
IconButton {
id: expandBtn
anchors.left: parent.left
anchors.margins: Tokens.padding.medium
anchors.verticalCenter: collapsedText.verticalCenter
font.pointSize: Tokens.font.size.large
icon: "keyboard_arrow_down"
inactiveOnColor: hovered ? Colors.palette.m3onSurface : Colors.palette.m3outline
opacity: root.isReasoning ? 0 : 1
rotation: root.expanded ? 180 : 0
type: IconButton.Text
Behavior on rotation {
Anim {
}
}
onClicked: root.expanded = !root.expanded
}
CustomText {
id: collapsedText
anchors.left: root.current.reasoningActive ? spinnerReasoning.right : expandBtn.right
anchors.margins: Tokens.padding.medium
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: 0
color: Colors.palette.m3outline
font.pointSize: Tokens.font.size.small
text: root.current.reasoningActive ? qsTr("Thinking...") : qsTr("Thought for %1s").arg((root.current.reasoningElapsedMs / 1000).toFixed(1))
Behavior on opacity {
Anim {
}
}
}
CustomClippingRect {
id: expandedRect
anchors.left: parent.left
anchors.right: parent.right
anchors.top: collapsedText.bottom
anchors.topMargin: Tokens.spacing.medium
color: Colors.palette.m3surfaceContainerLow
implicitHeight: root.expanded ? expandedText.implicitHeight + expandedText.anchors.margins * 2 : -anchors.topMargin
implicitWidth: expandedText.implicitWidth + expandedText.anchors.margins * 2
opacity: root.expanded ? 1 : 0
radius: Tokens.rounding.medium
visible: opacity > 0
Behavior on implicitHeight {
Anim {
type: Anim.DefaultEffects
}
}
Behavior on opacity {
Anim {
}
}
CustomText {
id: expandedText
anchors.fill: parent
anchors.margins: Tokens.padding.medium
color: Colors.palette.m3onSurface
font.pointSize: Tokens.font.size.small
text: root.current.reasoning
textFormat: CustomText.MarkdownText
wrapMode: Text.WordWrap
}
}
}