summaryrefslogtreecommitdiff
path: root/services/Clip.qml
diff options
context:
space:
mode:
Diffstat (limited to 'services/Clip.qml')
-rw-r--r--services/Clip.qml78
1 files changed, 76 insertions, 2 deletions
diff --git a/services/Clip.qml b/services/Clip.qml
index d03976c..59c460b 100644
--- a/services/Clip.qml
+++ b/services/Clip.qml
@@ -2,8 +2,11 @@ pragma Singleton
import Quickshell
import Quickshell.Io
-import QtQuick
+import Quickshell.Wayland
+
import qs.components
+import qs.utils
+import qs.services
Searchable {
id: root
@@ -15,6 +18,8 @@ Searchable {
property list<string> _clipImg: []
property list<string> _clipImgIds: _clipImg.map(p => p.split("/").pop().split(".").shift())
+ property var _clipMetadata: ({})
+
list: {
if (!_clipHist?.length)
return [];
@@ -41,16 +46,45 @@ Searchable {
const idStr = idNum >= 0 ? "" + idNum : "";
const imgPath = idStr ? imgMap[idStr] || "" : "";
const isImg = !!imgPath;
+ const metadata = _clipMetadata[idStr] || {};
return {
index: idNum,
isImage: isImg,
data: isImg ? imgPath : payload,
- raw: raw
+ raw: raw,
+ timestamp: metadata.timestamp || "",
+ appId: metadata.appId || "",
+ appTitle: metadata.appTitle || "",
+ appIcon: Quickshell.iconPath(AppSearch.guessIcon(metadata.appId), "image-missing")
};
});
}
+ Persistent {
+ id: clipMetaStore
+ filePath: Directories.clipHistMetaDataPath
+ adapter: JsonAdapter {
+ property var metadata: ({})
+ }
+ fileView.onLoaded: {
+ const meta = adapter.metadata;
+ for (const k in meta) {
+ if (meta[k].timestamp && typeof meta[k].timestamp === "string") {
+ meta[k].timestamp = new Date(meta[k].timestamp);
+ }
+ }
+ root._clipMetadata = meta;
+ }
+ // fileView.onAdapterUpdated: {
+ // root._clipMetadata = adapter.metadata;
+ // }
+ }
+
+ on_ClipMetadataChanged: {
+ clipMetaStore.adapter.metadata = _clipMetadata;
+ }
+
function transformSearch(search) {
return search.toLowerCase();
}
@@ -68,18 +102,57 @@ Searchable {
imgProc.running = true;
}
+ function _captureMetadata() {
+ const now = new Date();
+ const activeToplevel = ToplevelManager.activeToplevel;
+
+ Qt.callLater(() => {
+ clipProc.running = true;
+ clipProc.stdout.onceFinished = () => {
+ const lines = clipProc.stdout.text.split(/\r?\n/);
+ const firstLine = lines[0] || "";
+ const tab = firstLine.indexOf("\t");
+
+ if (tab > 0) {
+ const idStr = firstLine.slice(0, tab);
+ const n = parseInt(idStr, 10);
+ if (!Number.isNaN(n)) {
+ var newMetadata = {};
+ for (var k in _clipMetadata) {
+ if (_clipMetadata.hasOwnProperty(k))
+ newMetadata[k] = _clipMetadata[k];
+ }
+
+ newMetadata[idStr] = {
+ timestamp: now,
+ appId: activeToplevel ? activeToplevel.appId : "",
+ appTitle: activeToplevel ? activeToplevel.title : ""
+ };
+ _clipMetadata = newMetadata;
+ }
+ }
+ };
+ });
+ }
+
Process {
id: clipProc
running: true
command: ["cliphist", "-preview-width", 9 ** 9, "-max-items", 9 ** 9, "list"]
stdout: StdioCollector {
property bool pending: false
+ property var onceFinished: null
+
onStreamFinished: () => {
pending = true;
Qt.callLater(() => {
if (pending) {
pending = false;
_clipHist = this.text.split(/\r?\n/);
+ if (onceFinished) {
+ onceFinished();
+ onceFinished = null;
+ }
}
});
}
@@ -113,6 +186,7 @@ Searchable {
stdout: SplitParser {
onRead: line => {
+ _captureMetadata();
_update();
}
}