diff --git a/gpt4all-chat/CMakeLists.txt b/gpt4all-chat/CMakeLists.txt
index 81e086b4..1fe2c060 100644
--- a/gpt4all-chat/CMakeLists.txt
+++ b/gpt4all-chat/CMakeLists.txt
@@ -174,6 +174,8 @@ qt_add_qml_module(chat
icons/send_message.svg
icons/stop_generating.svg
icons/regenerate.svg
+ icons/caret_down.svg
+ icons/caret_right.svg
icons/chat.svg
icons/changelog.svg
icons/close.svg
diff --git a/gpt4all-chat/icons/caret_down.svg b/gpt4all-chat/icons/caret_down.svg
new file mode 100644
index 00000000..42f37b71
--- /dev/null
+++ b/gpt4all-chat/icons/caret_down.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/gpt4all-chat/icons/caret_right.svg b/gpt4all-chat/icons/caret_right.svg
new file mode 100644
index 00000000..81658b07
--- /dev/null
+++ b/gpt4all-chat/icons/caret_right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/gpt4all-chat/qml/ChatView.qml b/gpt4all-chat/qml/ChatView.qml
index 79dfeeab..87fd5ba9 100644
--- a/gpt4all-chat/qml/ChatView.qml
+++ b/gpt4all-chat/qml/ChatView.qml
@@ -715,7 +715,7 @@ Rectangle {
delegate: GridLayout {
width: listView.contentItem.width
- rows: 4
+ rows: 3
columns: 2
Item {
@@ -797,207 +797,8 @@ Rectangle {
}
}
-
- Item {
- Layout.row: 1
- Layout.column: 0
- Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
- Layout.topMargin: 5
- Layout.preferredWidth: 24
- Layout.preferredHeight: 24
- visible: consolidatedSources.length !== 0 && MySettings.localDocsShowReferences
-
- Image {
- id: sourcesIcon
- visible: false
- anchors.fill: parent
- sourceSize.width: 24
- sourceSize.height: 24
- mipmap: true
- source: "qrc:/gpt4all/icons/db.svg"
- }
-
- ColorOverlay {
- anchors.fill: sourcesIcon
- source: sourcesIcon
- color: theme.textColor
- }
- }
-
- RowLayout {
- Layout.row: 1
- Layout.column: 1
- Layout.topMargin: 5
- Layout.alignment: Qt.AlignVCenter
- visible: consolidatedSources.length !== 0 && MySettings.localDocsShowReferences
- TextArea {
- text: qsTr("Sources")
- padding: 0
- readOnly: true
- font.pixelSize: theme.fontSizeLarge
- font.bold: true
- color: theme.textColor
- }
- }
-
- ColumnLayout {
- Layout.row: 2
- Layout.column: 1
- visible: consolidatedSources.length !== 0 && MySettings.localDocsShowReferences
- Flow {
- Layout.fillWidth: true
- Layout.topMargin: 5
- spacing: 10
- visible: consolidatedSources.length !== 0
- Repeater {
- model: consolidatedSources
-
- delegate: Rectangle {
- radius: 10
- color: ma.containsMouse ? theme.sourcesBackgroundHovered : theme.sourcesBackground
- width: 200
- height: 75
-
- MouseArea {
- id: ma
- enabled: modelData.path !== ""
- anchors.fill: parent
- hoverEnabled: true
- onClicked: function() {
- Qt.openUrlExternally(modelData.fileUri)
- }
- }
-
- Rectangle {
- id: debugTooltip
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- width: 24
- height: 24
- color: "transparent"
- ToolTip {
- parent: debugTooltip
- visible: debugMouseArea.containsMouse
- text: modelData.text
- contentWidth: 900
- delay: 500
- }
- MouseArea {
- id: debugMouseArea
- anchors.fill: parent
- hoverEnabled: true
- }
- }
-
- ColumnLayout {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.margins: 10
- spacing: 0
- RowLayout {
- id: title
- spacing: 5
- Layout.maximumWidth: 180
- Item {
- Layout.preferredWidth: 24
- Layout.preferredHeight: 24
- Image {
- id: fileIcon
- anchors.fill: parent
- visible: false
- sourceSize.width: 24
- sourceSize.height: 24
- mipmap: true
- source: {
- if (modelData.file.endsWith(".txt"))
- return "qrc:/gpt4all/icons/file-txt.svg"
- else if (modelData.file.endsWith(".pdf"))
- return "qrc:/gpt4all/icons/file-pdf.svg"
- else if (modelData.file.endsWith(".md"))
- return "qrc:/gpt4all/icons/file-md.svg"
- else
- return "qrc:/gpt4all/icons/file.svg"
- }
- }
- ColorOverlay {
- anchors.fill: fileIcon
- source: fileIcon
- color: theme.textColor
- }
- }
- Text {
- Layout.maximumWidth: 156
- text: modelData.collection !== "" ? modelData.collection : qsTr("LocalDocs")
- font.pixelSize: theme.fontSizeLarge
- font.bold: true
- color: theme.styledTextColor
- elide: Qt.ElideRight
- }
- Rectangle {
- Layout.fillWidth: true
- color: "transparent"
- height: 1
- }
- }
- Text {
- Layout.fillHeight: true
- Layout.maximumWidth: 180
- Layout.maximumHeight: 55 - title.height
- text: modelData.file
- color: theme.textColor
- font.pixelSize: theme.fontSizeSmall
- elide: Qt.ElideRight
- wrapMode: Text.WrapAnywhere
- }
- }
- }
- }
- }
- }
-
- Item {
- Layout.row: 3
- Layout.column: 0
- Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
- Layout.topMargin: 5
- Layout.preferredWidth: 24
- Layout.preferredHeight: 24
- visible: consolidatedSources.length !== 0 && MySettings.localDocsShowReferences
- Image {
- id: answersIcon
- visible: false
- anchors.fill: parent
- sourceSize.width: 24
- sourceSize.height: 24
- mipmap: true
- source: "qrc:/gpt4all/icons/info.svg"
- }
-
- ColorOverlay {
- anchors.fill: answersIcon
- source: answersIcon
- color: theme.textColor
- }
- }
-
- RowLayout {
- Layout.row: 3
- Layout.column: 1
- Layout.topMargin: 5
- Layout.alignment: Qt.AlignVCenter
- visible: consolidatedSources.length !== 0 && MySettings.localDocsShowReferences
- TextArea {
- text: qsTr("Answer")
- padding: 0
- font.pixelSize: theme.fontSizeLarge
- font.bold: true
- readOnly: true
- color: theme.textColor
- }
- }
-
ColumnLayout {
- Layout.row: 4
+ Layout.row: 1
Layout.column: 1
Layout.fillWidth: true
TextArea {
@@ -1162,6 +963,230 @@ Rectangle {
}
}
}
+
+ Item {
+ Layout.row: 2
+ Layout.column: 1
+ Layout.topMargin: 5
+ Layout.alignment: Qt.AlignVCenter
+ Layout.preferredWidth: childrenRect.width
+ Layout.preferredHeight: childrenRect.height
+ visible: consolidatedSources.length !== 0 && MySettings.localDocsShowReferences && (!currentResponse || !currentChat.responseInProgress)
+
+ MyButton {
+ backgroundColor: theme.sourcesBackground
+ backgroundColorHovered: theme.sourcesBackgroundHovered
+ contentItem: RowLayout {
+ anchors.centerIn: parent
+
+ Item {
+ Layout.preferredWidth: 24
+ Layout.preferredHeight: 24
+
+ Image {
+ id: sourcesIcon
+ visible: false
+ anchors.fill: parent
+ sourceSize.width: 24
+ sourceSize.height: 24
+ mipmap: true
+ source: "qrc:/gpt4all/icons/db.svg"
+ }
+
+ ColorOverlay {
+ anchors.fill: sourcesIcon
+ source: sourcesIcon
+ color: theme.textColor
+ }
+ }
+
+ TextArea {
+ text: consolidatedSources.length + " " + qsTr("Local Sources")
+ padding: 0
+ readOnly: true
+ font.pixelSize: theme.fontSizeLarge
+ font.bold: true
+ color: theme.styledTextColor
+ }
+
+ Item {
+ Layout.preferredWidth: caret.width
+ Layout.preferredHeight: caret.height
+ Image {
+ id: caret
+ anchors.centerIn: parent
+ visible: false
+ sourceSize.width: theme.fontSizeLarge
+ sourceSize.height: theme.fontSizeLarge
+ mipmap: true
+ source: {
+ if (sourcesLayout.state === "collapsed")
+ return "qrc:/gpt4all/icons/caret_right.svg";
+ else
+ return "qrc:/gpt4all/icons/caret_down.svg";
+ }
+ }
+
+ ColorOverlay {
+ anchors.fill: caret
+ source: caret
+ color: theme.textColor
+ }
+ }
+ }
+
+ onClicked: {
+ if (sourcesLayout.state === "collapsed")
+ sourcesLayout.state = "expanded";
+ else
+ sourcesLayout.state = "collapsed";
+ }
+ }
+ }
+
+ ColumnLayout {
+ id: sourcesLayout
+ Layout.row: 3
+ Layout.column: 1
+ visible: consolidatedSources.length !== 0 && MySettings.localDocsShowReferences && (!currentResponse || !currentChat.responseInProgress)
+ clip: true
+ Layout.fillWidth: true
+ Layout.preferredHeight: 0
+ state: "collapsed"
+ states: [
+ State {
+ name: "expanded"
+ PropertyChanges { target: sourcesLayout; Layout.preferredHeight: childrenRect.height }
+ },
+ State {
+ name: "collapsed"
+ PropertyChanges { target: sourcesLayout; Layout.preferredHeight: 0 }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ SequentialAnimation {
+ PropertyAnimation {
+ target: sourcesLayout
+ property: "Layout.preferredHeight"
+ duration: 300
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+ ]
+
+ Flow {
+ Layout.fillWidth: true
+ Layout.topMargin: 5
+ spacing: 10
+ visible: consolidatedSources.length !== 0
+ Repeater {
+ model: consolidatedSources
+
+ delegate: Rectangle {
+ radius: 10
+ color: ma.containsMouse ? theme.sourcesBackgroundHovered : theme.sourcesBackground
+ width: 200
+ height: 75
+
+ MouseArea {
+ id: ma
+ enabled: modelData.path !== ""
+ anchors.fill: parent
+ hoverEnabled: true
+ onClicked: function() {
+ Qt.openUrlExternally(modelData.fileUri)
+ }
+ }
+
+ Rectangle {
+ id: debugTooltip
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ width: 24
+ height: 24
+ color: "transparent"
+ ToolTip {
+ parent: debugTooltip
+ visible: debugMouseArea.containsMouse
+ text: modelData.text
+ contentWidth: 900
+ delay: 500
+ }
+ MouseArea {
+ id: debugMouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ }
+ }
+
+ ColumnLayout {
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.margins: 10
+ spacing: 0
+ RowLayout {
+ id: title
+ spacing: 5
+ Layout.maximumWidth: 180
+ Item {
+ Layout.preferredWidth: 24
+ Layout.preferredHeight: 24
+ Image {
+ id: fileIcon
+ anchors.fill: parent
+ visible: false
+ sourceSize.width: 24
+ sourceSize.height: 24
+ mipmap: true
+ source: {
+ if (modelData.file.endsWith(".txt"))
+ return "qrc:/gpt4all/icons/file-txt.svg"
+ else if (modelData.file.endsWith(".pdf"))
+ return "qrc:/gpt4all/icons/file-pdf.svg"
+ else if (modelData.file.endsWith(".md"))
+ return "qrc:/gpt4all/icons/file-md.svg"
+ else
+ return "qrc:/gpt4all/icons/file.svg"
+ }
+ }
+ ColorOverlay {
+ anchors.fill: fileIcon
+ source: fileIcon
+ color: theme.textColor
+ }
+ }
+ Text {
+ Layout.maximumWidth: 156
+ text: modelData.collection !== "" ? modelData.collection : qsTr("LocalDocs")
+ font.pixelSize: theme.fontSizeLarge
+ font.bold: true
+ color: theme.styledTextColor
+ elide: Qt.ElideRight
+ }
+ Rectangle {
+ Layout.fillWidth: true
+ color: "transparent"
+ height: 1
+ }
+ }
+ Text {
+ Layout.fillHeight: true
+ Layout.maximumWidth: 180
+ Layout.maximumHeight: 55 - title.height
+ text: modelData.file
+ color: theme.textColor
+ font.pixelSize: theme.fontSizeSmall
+ elide: Qt.ElideRight
+ wrapMode: Text.WrapAnywhere
+ }
+ }
+ }
+ }
+ }
+ }
}
property bool shouldAutoScroll: true
@@ -1170,11 +1195,15 @@ Rectangle {
Connections {
target: currentChat
function onResponseChanged() {
- if (listView.shouldAutoScroll) {
- listView.isAutoScrolling = true
- listView.positionViewAtEnd()
- listView.isAutoScrolling = false
- }
+ listView.scrollToEnd()
+ }
+ }
+
+ function scrollToEnd() {
+ if (listView.shouldAutoScroll) {
+ listView.isAutoScrolling = true
+ listView.positionViewAtEnd()
+ listView.isAutoScrolling = false
}
}