feat: Improve Chat UI

Move send and compress button to right bottom corner
This commit is contained in:
Petr Mironychev
2026-04-23 01:48:17 +02:00
parent 6b069b55e3
commit ca0a47b160
5 changed files with 128 additions and 67 deletions

View File

@@ -62,7 +62,22 @@ ChatRootView {
} }
} }
QoABusyOverlay {
id: compressingOverlay
z: 50
anchors.fill: mainColumn
anchors.topMargin: topBar.height
anchors.bottomMargin: bottomBar.height
active: root.isCompressing
text: qsTr("Compressing chat…")
}
ColumnLayout { ColumnLayout {
id: mainColumn
anchors.fill: parent anchors.fill: parent
spacing: 0 spacing: 0
@@ -72,12 +87,9 @@ ChatRootView {
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.preferredHeight: childrenRect.height + 10 Layout.preferredHeight: childrenRect.height + 10
isCompressing: root.isCompressing
saveButton.onClicked: root.showSaveDialog() saveButton.onClicked: root.showSaveDialog()
loadButton.onClicked: root.showLoadDialog() loadButton.onClicked: root.showLoadDialog()
clearButton.onClicked: root.clearChat() clearButton.onClicked: root.clearChat()
compressButton.onClicked: compressConfirmDialog.open()
cancelCompressButton.onClicked: root.cancelCompression()
tokensBadge { tokensBadge {
text: qsTr("%1/%2").arg(root.inputTokensCount).arg(root.chatModel.tokensThreshold) text: qsTr("%1/%2").arg(root.inputTokensCount).arg(root.chatModel.tokensThreshold)
} }
@@ -477,12 +489,16 @@ ChatRootView {
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.preferredHeight: 40 Layout.preferredHeight: 40
isCompressing: root.isCompressing
sendButton.onClicked: !root.isRequestInProgress ? root.sendChatMessage() sendButton.onClicked: !root.isRequestInProgress ? root.sendChatMessage()
: root.cancelRequest() : root.cancelRequest()
sendButton.icon.source: !root.isRequestInProgress ? "qrc:/qt/qml/ChatView/icons/chat-icon.svg" sendButton.icon.source: !root.isRequestInProgress ? "qrc:/qt/qml/ChatView/icons/chat-icon.svg"
: "qrc:/qt/qml/ChatView/icons/chat-pause-icon.svg" : "qrc:/qt/qml/ChatView/icons/chat-pause-icon.svg"
sendButton.text: !root.isRequestInProgress ? qsTr("Send") : qsTr("Stop")
sendButton.ToolTip.text: !root.isRequestInProgress ? qsTr("Send message to LLM %1").arg(Qt.platform.os === "osx" ? "Cmd+Return" : "Ctrl+Return") sendButton.ToolTip.text: !root.isRequestInProgress ? qsTr("Send message to LLM %1").arg(Qt.platform.os === "osx" ? "Cmd+Return" : "Ctrl+Return")
: qsTr("Stop") : qsTr("Stop")
compressButton.onClicked: compressConfirmDialog.open()
cancelCompressButton.onClicked: root.cancelCompression()
syncOpenFiles { syncOpenFiles {
checked: root.isSyncOpenFiles checked: root.isSyncOpenFiles
onCheckedChanged: root.setIsSyncOpenFiles(bottomBar.syncOpenFiles.checked) onCheckedChanged: root.setIsSyncOpenFiles(bottomBar.syncOpenFiles.checked)

View File

@@ -15,6 +15,10 @@ Rectangle {
property alias attachFiles: attachFilesId property alias attachFiles: attachFilesId
property alias attachImages: attachImagesId property alias attachImages: attachImagesId
property alias linkFiles: linkFilesId property alias linkFiles: linkFilesId
property alias compressButton: compressButtonId
property alias cancelCompressButton: cancelCompressButtonId
property bool isCompressing: false
color: palette.window.hslLightness > 0.5 ? color: palette.window.hslLightness > 0.5 ?
Qt.darker(palette.window, 1.1) : Qt.darker(palette.window, 1.1) :
@@ -33,17 +37,6 @@ Rectangle {
spacing: 10 spacing: 10
QoAButton {
id: sendButtonId
icon {
height: 15
width: 15
}
ToolTip.visible: hovered
ToolTip.delay: 250
}
QoAButton { QoAButton {
id: attachFilesId id: attachFilesId
@@ -95,5 +88,66 @@ Rectangle {
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
} }
Row {
id: compressingRow
visible: root.isCompressing
spacing: 6
BusyIndicator {
id: compressBusyIndicator
anchors.verticalCenter: parent.verticalCenter
running: root.isCompressing
width: 16
height: 16
}
Text {
text: qsTr("Compressing...")
anchors.verticalCenter: parent.verticalCenter
color: palette.text
font.pixelSize: 12
}
QoAButton {
id: cancelCompressButtonId
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Cancel")
ToolTip.visible: hovered
ToolTip.delay: 250
ToolTip.text: qsTr("Cancel compression")
}
}
QoAButton {
id: compressButtonId
visible: !root.isCompressing
text: qsTr("Compress")
icon {
source: "qrc:/qt/qml/ChatView/icons/compress-icon.svg"
height: 15
width: 15
}
ToolTip.visible: hovered
ToolTip.delay: 250
ToolTip.text: qsTr("Compress chat (create summarized copy using LLM)")
}
QoAButton {
id: sendButtonId
icon {
height: 15
width: 15
}
ToolTip.visible: hovered
ToolTip.delay: 250
}
} }
} }

View File

@@ -13,8 +13,6 @@ Rectangle {
property alias saveButton: saveButtonId property alias saveButton: saveButtonId
property alias loadButton: loadButtonId property alias loadButton: loadButtonId
property alias clearButton: clearButtonId property alias clearButton: clearButtonId
property alias compressButton: compressButtonId
property alias cancelCompressButton: cancelCompressButtonId
property alias tokensBadge: tokensBadgeId property alias tokensBadge: tokensBadgeId
property alias recentPath: recentPathId property alias recentPath: recentPathId
property alias openChatHistory: openChatHistoryId property alias openChatHistory: openChatHistoryId
@@ -26,8 +24,6 @@ Rectangle {
property alias configSelector: configSelectorId property alias configSelector: configSelectorId
property alias roleSelector: roleSelector property alias roleSelector: roleSelector
property bool isCompressing: false
color: palette.window.hslLightness > 0.5 ? color: palette.window.hslLightness > 0.5 ?
Qt.darker(palette.window, 1.1) : Qt.darker(palette.window, 1.1) :
Qt.lighter(palette.window, 1.1) Qt.lighter(palette.window, 1.1)
@@ -242,55 +238,6 @@ Rectangle {
QoASeparator {} QoASeparator {}
QoAButton {
id: compressButtonId
visible: !root.isCompressing
icon {
source: "qrc:/qt/qml/ChatView/icons/compress-icon.svg"
height: 15
width: 15
}
ToolTip.visible: hovered
ToolTip.delay: 250
ToolTip.text: qsTr("Compress chat (create summarized copy using LLM)")
}
Row {
id: compressingRow
visible: root.isCompressing
spacing: 6
BusyIndicator {
id: compressBusyIndicator
anchors.verticalCenter: parent.verticalCenter
running: root.isCompressing
width: 16
height: 16
}
Text {
text: qsTr("Compressing...")
height: parent.height
color: palette.text
font.pixelSize: 12
verticalAlignment: Text.AlignVCenter
}
QoAButton {
id: cancelCompressButtonId
text: qsTr("Cancel")
ToolTip.visible: hovered
ToolTip.delay: 250
ToolTip.text: qsTr("Cancel compression")
}
}
QoAButton { QoAButton {
id: contextButtonId id: contextButtonId

View File

@@ -10,6 +10,7 @@ qt_add_qml_module(QodeAssistUIControls
QML_FILES QML_FILES
qml/Badge.qml qml/Badge.qml
qml/QoAButton.qml qml/QoAButton.qml
qml/QoABusyOverlay.qml
qml/QoATextSlider.qml qml/QoATextSlider.qml
qml/QoAComboBox.qml qml/QoAComboBox.qml
qml/FadeListItemAnimation.qml qml/FadeListItemAnimation.qml

View File

@@ -0,0 +1,43 @@
// Copyright (C) 2024-2026 Petr Mironychev
// SPDX-License-Identifier: GPL-3.0-or-later
import QtQuick
import QtQuick.Controls
Rectangle {
id: root
property alias text: label.text
property bool active: false
visible: active
color: Qt.rgba(palette.window.r, palette.window.g, palette.window.b, 0.75)
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.AllButtons
hoverEnabled: true
preventStealing: true
onWheel: function(wheel) { wheel.accepted = true }
}
Column {
anchors.centerIn: parent
spacing: 10
BusyIndicator {
anchors.horizontalCenter: parent.horizontalCenter
running: root.active
implicitWidth: 36
implicitHeight: 36
}
Text {
id: label
anchors.horizontalCenter: parent.horizontalCenter
color: palette.text
font.pixelSize: 13
}
}
}