diff --git a/.config/quickshell/modules/common/XdgDirectories.qml b/.config/quickshell/modules/common/XdgDirectories.qml index 51bf2d0ca..c8297fbb1 100644 --- a/.config/quickshell/modules/common/XdgDirectories.qml +++ b/.config/quickshell/modules/common/XdgDirectories.qml @@ -9,4 +9,5 @@ Singleton { readonly property string state: StandardPaths.standardLocations(StandardPaths.StateLocation)[0] readonly property string cache: StandardPaths.standardLocations(StandardPaths.CacheLocation)[0] readonly property string pictures: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0] + readonly property string downloads: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0] } diff --git a/.config/quickshell/modules/sidebarLeft/aiChat/AiMessage.qml b/.config/quickshell/modules/sidebarLeft/aiChat/AiMessage.qml index 43af48654..9d8f1ae02 100644 --- a/.config/quickshell/modules/sidebarLeft/aiChat/AiMessage.qml +++ b/.config/quickshell/modules/sidebarLeft/aiChat/AiMessage.qml @@ -198,6 +198,7 @@ Rectangle { copyButton.activated = false } } + StyledToolTip { content: qsTr("Copy") } diff --git a/.config/quickshell/modules/sidebarLeft/aiChat/MessageCodeBlock.qml b/.config/quickshell/modules/sidebarLeft/aiChat/MessageCodeBlock.qml index 024103459..c38afb9b6 100644 --- a/.config/quickshell/modules/sidebarLeft/aiChat/MessageCodeBlock.qml +++ b/.config/quickshell/modules/sidebarLeft/aiChat/MessageCodeBlock.qml @@ -6,6 +6,7 @@ import "root:/modules/common/" import "root:/modules/common/widgets" import "../" import "root:/modules/common/functions/string_utils.js" as StringUtils +import "root:/modules/common/functions/file_utils.js" as FileUtils import QtQuick import QtQuick.Controls import QtQuick.Layouts @@ -22,7 +23,7 @@ ColumnLayout { property bool renderMarkdown: parent?.renderMarkdown ?? true property bool enableMouseSelection: parent?.enableMouseSelection ?? false property var segmentContent: parent?.segmentContent ?? ({}) - property var segmentLang: parent?.segmentLang ?? "plaintext" + property var segmentLang: parent?.segmentLang ?? "txt" property var messageData: parent?.messageData ?? {} property real codeBlockBackgroundRounding: Appearance.rounding.small @@ -66,14 +67,51 @@ ColumnLayout { Item { Layout.fillWidth: true } - AiMessageControlButton { - id: copyCodeButton - buttonIcon: "content_copy" - onClicked: { - Hyprland.dispatch(`exec wl-copy '${StringUtils.shellSingleQuoteEscape(segmentContent)}'`) + ButtonGroup { + AiMessageControlButton { + id: copyCodeButton + buttonIcon: activated ? "inventory" : "content_copy" + + onClicked: { + Hyprland.dispatch(`exec wl-copy '${StringUtils.shellSingleQuoteEscape(segmentContent)}'`) + copyCodeButton.activated = true + copyIconTimer.restart() + } + + Timer { + id: copyIconTimer + interval: 1500 + repeat: false + onTriggered: { + copyCodeButton.activated = false + } + } + StyledToolTip { + content: qsTr("Copy code") + } } - StyledToolTip { - content: qsTr("Copy code") + AiMessageControlButton { + id: saveCodeButton + buttonIcon: activated ? "check" : "save" + + onClicked: { + Hyprland.dispatch(`exec echo '${StringUtils.shellSingleQuoteEscape(segmentContent)}' > '${FileUtils.trimFileProtocol(XdgDirectories.downloads)}/code.${segmentLang || "txt"}'`) + Hyprland.dispatch(`exec notify-send 'Code saved to file' '${FileUtils.trimFileProtocol(XdgDirectories.downloads)}/code.${segmentLang || "txt"}'`) + saveCodeButton.activated = true + saveIconTimer.restart() + } + + Timer { + id: saveIconTimer + interval: 1500 + repeat: false + onTriggered: { + saveCodeButton.activated = false + } + } + StyledToolTip { + content: qsTr("Save to Downloads") + } } } }