aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/assistant/Card.qml
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/assistant/Card.qml')
-rw-r--r--desktop/assistant/Card.qml68
1 files changed, 58 insertions, 10 deletions
diff --git a/desktop/assistant/Card.qml b/desktop/assistant/Card.qml
index a2f8e28..810920f 100644
--- a/desktop/assistant/Card.qml
+++ b/desktop/assistant/Card.qml
@@ -28,7 +28,7 @@ Rectangle {
property real fullHeight: 600 // the chat state's height, set by the window
readonly property string mode: card.canvas.mode
- readonly property bool panel: card.canvas.historyOpen || card.canvas.pickerOpen
+ readonly property bool panel: card.canvas.historyOpen || card.canvas.pickerOpen || card.canvas.modelsOpen
readonly property bool tall: card.mode === "chat" || card.panel
// Bottom-up: the input, then the actions (file state), then the chips.
@@ -49,13 +49,15 @@ Rectangle {
// Keys reach a focused item, never the window (AGENTS.md); the card is
// the ancestor of every text field, so their Escape bubbles here.
Keys.onEscapePressed: card.canvas.back()
- // Ctrl+N and Ctrl+H do what the New and History buttons do.
+ // Ctrl+N, Ctrl+H and Ctrl+M do what New, History and the model menu do.
Keys.onPressed: event => {
if (!(event.modifiers & Qt.ControlModifier)) return;
if (event.key === Qt.Key_N && card.canvas.connected) {
card.canvas.fresh(); card.canvas.historyOpen = false; input.forceActiveFocus();
} else if (event.key === Qt.Key_H) {
card.canvas.historyOpen ? card.canvas.back() : card.canvas.showHistory();
+ } else if (event.key === Qt.Key_M && card.canvas.connected) {
+ card.canvas.modelsOpen ? card.canvas.back() : card.canvas.showModels();
} else return;
event.accepted = true;
}
@@ -90,13 +92,40 @@ Rectangle {
anchors { top: parent.top; left: parent.left; right: parent.right; margins: 14 }
height: 32
- Text {
+ // The chat's model, a click opens the model panel. nf-fa-cloud for a
+ // cloud one, nf-fa-angle_down after it.
+ Row {
+ id: modelRow
anchors { left: parent.left; verticalCenter: parent.verticalCenter }
- text: !card.canvas.connected ? "assistant not running"
- : card.canvas.swapping ? `loading ${card.canvas.swapping}…`
- : card.canvas.model || "assistant"
- color: card.canvas.connected ? Theme.text : Theme.red
- font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 }
+ spacing: 6
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ visible: card.canvas.connected && !card.canvas.swapping && card.canvas.cloud
+ text: ""
+ color: Theme.subtext
+ font { family: Theme.iconFamily; pixelSize: Theme.fontSize - 4 }
+ }
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ text: !card.canvas.connected ? "assistant not running"
+ : card.canvas.swapping ? `loading ${card.canvas.swapping}…`
+ : card.canvas.wanted || card.canvas.model || "assistant"
+ color: card.canvas.connected ? Theme.text : Theme.red
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 }
+ }
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ visible: card.canvas.connected
+ text: ""
+ color: Theme.subtext
+ font { family: Theme.iconFamily; pixelSize: Theme.fontSize - 4 }
+ }
+ }
+ MouseArea {
+ anchors.fill: modelRow
+ enabled: card.canvas.connected
+ cursorShape: Qt.PointingHandCursor
+ onClicked: card.canvas.modelsOpen ? card.canvas.back() : card.canvas.showModels()
}
Row {
@@ -436,7 +465,7 @@ Rectangle {
text: ""
font.family: Theme.iconFamily
onClicked: {
- card.canvas.historyOpen = false;
+ card.canvas.historyOpen = card.canvas.modelsOpen = false;
card.canvas.pickerOpen = !card.canvas.pickerOpen;
}
}
@@ -466,7 +495,7 @@ Rectangle {
id: box
anchors {
bottom: parent.bottom; left: mic.right; leftMargin: 8
- right: history.left; rightMargin: 8
+ right: modelBtn.left; rightMargin: 8
}
// Grows with the text up to six lines, then scrolls.
height: Math.min(input.contentHeight, 6 * input.font.pixelSize * 1.4) + 16
@@ -524,6 +553,20 @@ Rectangle {
}
}
+ // The model menu outside chat, where there is no header; nf-fa-cloud
+ // when the next question goes to a cloud model.
+ Button {
+ id: modelBtn
+ visible: card.mode !== "chat"
+ width: visible ? implicitWidth : 0
+ anchors { bottom: parent.bottom; right: history.left; rightMargin: visible ? 8 : 0 }
+ height: box.height
+ icon: card.canvas.cloud ? "" : ""
+ text: "Model"
+ enabled: card.canvas.connected
+ onClicked: card.canvas.modelsOpen ? card.canvas.back() : card.canvas.showModels()
+ }
+
// History from every state; in chat the header has it too.
Button {
id: history
@@ -571,5 +614,10 @@ Rectangle {
visible: card.canvas.pickerOpen
canvas: card.canvas
}
+ Models {
+ anchors.fill: parent
+ visible: card.canvas.modelsOpen
+ canvas: card.canvas
+ }
}
}