ai: fade in response

This commit is contained in:
end-4
2025-10-12 12:58:03 +02:00
parent 79b49bd57e
commit a6e360c1db
2 changed files with 84 additions and 32 deletions
@@ -348,6 +348,9 @@ Singleton {
property JsonObject translator: JsonObject { property JsonObject translator: JsonObject {
property int delay: 300 // Delay before sending request. Reduces (potential) rate limits and lag. property int delay: 300 // Delay before sending request. Reduces (potential) rate limits and lag.
} }
property JsonObject ai: JsonObject {
property bool textFadeIn: true
}
property JsonObject booru: JsonObject { property JsonObject booru: JsonObject {
property bool allowNsfw: false property bool allowNsfw: false
property string defaultProvider: "yandere" property string defaultProvider: "yandere"
@@ -8,6 +8,7 @@ import qs.modules.common.functions
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import Quickshell
import Quickshell.Hyprland import Quickshell.Hyprland
ColumnLayout { ColumnLayout {
@@ -22,6 +23,8 @@ ColumnLayout {
property list<string> renderedLatexHashes: [] property list<string> renderedLatexHashes: []
property string renderedSegmentContent: "" property string renderedSegmentContent: ""
property string shownText: ""
property bool fadeChunkSplitting: !editing && !/\n\|/.test(shownText) && Config.options.sidebar.ai.textFadeIn
Layout.fillWidth: true Layout.fillWidth: true
@@ -73,7 +76,7 @@ ColumnLayout {
renderLatex() renderLatex()
} else { } else {
// console.log("Editing mode enabled", segmentContent) // console.log("Editing mode enabled", segmentContent)
textArea.text = segmentContent root.shownText = segmentContent
} }
} }
@@ -88,7 +91,7 @@ ColumnLayout {
onRenderedSegmentContentChanged: { onRenderedSegmentContentChanged: {
// console.log("Rendered segment content changed: " + renderedSegmentContent); // console.log("Rendered segment content changed: " + renderedSegmentContent);
if (renderedSegmentContent) { if (renderedSegmentContent) {
textArea.text = renderedSegmentContent; root.shownText = renderedSegmentContent;
} }
} }
@@ -104,8 +107,46 @@ ColumnLayout {
} }
} }
TextArea { spacing: 0
Repeater {
id: textLinesRepeater
property list<real> textLineOpacities: []
model: ScriptModel {
// Split by either double newlines or single newlines in a list
values: root.fadeChunkSplitting ? root.shownText.split(/\n\n|\n(?= {0,2}[-\*])/g).filter(line => line.trim() !== "") : [root.shownText]
onValuesChanged: {
while (textLinesRepeater.textLineOpacities.length < values.length) {
textLinesRepeater.textLineOpacities.push(root.messageData.done ? 1 : 0);
}
}
}
delegate: TextArea {
id: textArea id: textArea
required property int index
required property string modelData
// Fade in animation
visible: opacity > 0
opacity: fadeChunkSplitting ? (textLinesRepeater.textLineOpacities[index] ?? (root.messageData.done ? 1 : 0)) : 1
Connections {
target: root.messageData
function onDoneChanged() {
if (root.messageData.done) {
textLinesRepeater.textLineOpacities[textArea.index] = 1
}
}
}
Connections {
target: textLinesRepeater.model
function onValuesChanged() {
if (textLinesRepeater.model.values.length > textArea.index + 1) {
textLinesRepeater.textLineOpacities[textArea.index] = 1
}
}
}
Behavior on opacity {
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
}
Layout.fillWidth: true Layout.fillWidth: true
readOnly: !editing readOnly: !editing
@@ -119,7 +160,7 @@ ColumnLayout {
wrapMode: TextEdit.Wrap wrapMode: TextEdit.Wrap
color: messageData.thinking ? Appearance.colors.colSubtext : Appearance.colors.colOnLayer1 color: messageData.thinking ? Appearance.colors.colSubtext : Appearance.colors.colOnLayer1
textFormat: renderMarkdown ? TextEdit.MarkdownText : TextEdit.PlainText textFormat: renderMarkdown ? TextEdit.MarkdownText : TextEdit.PlainText
text: Translation.tr("Waiting for response...") text: modelData
onTextChanged: { onTextChanged: {
if (!root.editing) return if (!root.editing) return
@@ -138,5 +179,13 @@ ColumnLayout {
cursorShape: parent.hoveredLink !== "" ? Qt.PointingHandCursor : cursorShape: parent.hoveredLink !== "" ? Qt.PointingHandCursor :
(enableMouseSelection || editing) ? Qt.IBeamCursor : Qt.ArrowCursor (enableMouseSelection || editing) ? Qt.IBeamCursor : Qt.ArrowCursor
} }
// Rectangle {
// anchors.fill: parent
// color: "#22786378"
// border.width: 1
// border.color: "#7E7E7E"
// }
}
} }
} }