forked from Shinonome/dots-hyprland
ai: fade in response
This commit is contained in:
@@ -348,6 +348,9 @@ Singleton {
|
||||
property JsonObject translator: JsonObject {
|
||||
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 bool allowNsfw: false
|
||||
property string defaultProvider: "yandere"
|
||||
|
||||
@@ -8,6 +8,7 @@ import qs.modules.common.functions
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
|
||||
ColumnLayout {
|
||||
@@ -22,6 +23,8 @@ ColumnLayout {
|
||||
property list<string> renderedLatexHashes: []
|
||||
|
||||
property string renderedSegmentContent: ""
|
||||
property string shownText: ""
|
||||
property bool fadeChunkSplitting: !editing && !/\n\|/.test(shownText) && Config.options.sidebar.ai.textFadeIn
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
@@ -73,7 +76,7 @@ ColumnLayout {
|
||||
renderLatex()
|
||||
} else {
|
||||
// console.log("Editing mode enabled", segmentContent)
|
||||
textArea.text = segmentContent
|
||||
root.shownText = segmentContent
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +91,7 @@ ColumnLayout {
|
||||
onRenderedSegmentContentChanged: {
|
||||
// console.log("Rendered segment content changed: " + renderedSegmentContent);
|
||||
if (renderedSegmentContent) {
|
||||
textArea.text = renderedSegmentContent;
|
||||
root.shownText = renderedSegmentContent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,39 +107,85 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
|
||||
TextArea {
|
||||
id: textArea
|
||||
|
||||
Layout.fillWidth: true
|
||||
readOnly: !editing
|
||||
selectByMouse: enableMouseSelection || editing
|
||||
renderType: Text.NativeRendering
|
||||
font.family: Appearance.font.family.reading
|
||||
font.hintingPreference: Font.PreferNoHinting // Prevent weird bold text
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
selectedTextColor: Appearance.m3colors.m3onSecondaryContainer
|
||||
selectionColor: Appearance.colors.colSecondaryContainer
|
||||
wrapMode: TextEdit.Wrap
|
||||
color: messageData.thinking ? Appearance.colors.colSubtext : Appearance.colors.colOnLayer1
|
||||
textFormat: renderMarkdown ? TextEdit.MarkdownText : TextEdit.PlainText
|
||||
text: Translation.tr("Waiting for response...")
|
||||
|
||||
onTextChanged: {
|
||||
if (!root.editing) return
|
||||
segmentContent = text
|
||||
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
|
||||
required property int index
|
||||
required property string modelData
|
||||
|
||||
onLinkActivated: (link) => {
|
||||
Qt.openUrlExternally(link)
|
||||
GlobalStates.sidebarLeftOpen = false
|
||||
}
|
||||
// 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)
|
||||
}
|
||||
|
||||
MouseArea { // Pointing hand for links
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton // Only for hover
|
||||
hoverEnabled: true
|
||||
cursorShape: parent.hoveredLink !== "" ? Qt.PointingHandCursor :
|
||||
(enableMouseSelection || editing) ? Qt.IBeamCursor : Qt.ArrowCursor
|
||||
Layout.fillWidth: true
|
||||
readOnly: !editing
|
||||
selectByMouse: enableMouseSelection || editing
|
||||
renderType: Text.NativeRendering
|
||||
font.family: Appearance.font.family.reading
|
||||
font.hintingPreference: Font.PreferNoHinting // Prevent weird bold text
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
selectedTextColor: Appearance.m3colors.m3onSecondaryContainer
|
||||
selectionColor: Appearance.colors.colSecondaryContainer
|
||||
wrapMode: TextEdit.Wrap
|
||||
color: messageData.thinking ? Appearance.colors.colSubtext : Appearance.colors.colOnLayer1
|
||||
textFormat: renderMarkdown ? TextEdit.MarkdownText : TextEdit.PlainText
|
||||
text: modelData
|
||||
|
||||
onTextChanged: {
|
||||
if (!root.editing) return
|
||||
segmentContent = text
|
||||
}
|
||||
|
||||
onLinkActivated: (link) => {
|
||||
Qt.openUrlExternally(link)
|
||||
GlobalStates.sidebarLeftOpen = false
|
||||
}
|
||||
|
||||
MouseArea { // Pointing hand for links
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton // Only for hover
|
||||
hoverEnabled: true
|
||||
cursorShape: parent.hoveredLink !== "" ? Qt.PointingHandCursor :
|
||||
(enableMouseSelection || editing) ? Qt.IBeamCursor : Qt.ArrowCursor
|
||||
}
|
||||
|
||||
// Rectangle {
|
||||
// anchors.fill: parent
|
||||
// color: "#22786378"
|
||||
// border.width: 1
|
||||
// border.color: "#7E7E7E"
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user