Clipboard: better preview box

This commit is contained in:
Lemmy
2026-01-06 22:05:52 -05:00
parent 7e4c2e085c
commit 8f2f968a30
4 changed files with 70 additions and 32 deletions
+48 -15
View File
@@ -110,32 +110,47 @@ Item {
height: width
}
Image {
anchors.fill: parent
anchors.margins: Style.marginS
source: imageDataUrl
visible: isImageContent && !loadingFullContent && imageDataUrl !== ""
fillMode: Image.PreserveAspectFit
}
// Preview for image entry
ColumnLayout {
anchors.fill: parent
anchors.margins: Style.marginS
spacing: Style.marginXS
visible: !isImageContent && !loadingFullContent
spacing: Style.marginS
visible: isImageContent && !loadingFullContent && imageDataUrl !== ""
Image {
id: previewImage
Layout.fillWidth: true
Layout.fillHeight: true
source: imageDataUrl
fillMode: Image.PreserveAspectFit
}
NDivider {
Layout.fillWidth: true
Layout.bottomMargin: Style.marginS
}
NText {
Layout.fillWidth: true
visible: fullContent.length > 0
text: {
const chars = fullContent.length;
const words = fullContent.split(/\s+/).filter(w => w.length > 0).length;
const lines = fullContent.split('\n').length;
return `${chars} chars, ${words} words, ${lines} lines`;
const meta = ClipboardService.parseImageMeta(currentItem?.preview);
if (meta)
return `${meta.fmt} ${meta.w}×${meta.h} ${meta.size}`;
// Fallback to basic info
const format = (currentItem?.mime || "image").split("/")[1]?.toUpperCase() || "Image";
return `${format} ${previewImage.implicitWidth}×${previewImage.implicitHeight}`;
}
pointSize: Style.fontSizeS
color: Color.mOnSurfaceVariant
}
}
// Preview for text entry
ColumnLayout {
anchors.fill: parent
anchors.margins: Style.marginS
spacing: Style.marginS
visible: !isImageContent && !loadingFullContent
NScrollView {
Layout.fillWidth: true
@@ -152,6 +167,24 @@ Item {
color: Color.mOnSurface
}
}
NDivider {
Layout.fillWidth: true
Layout.bottomMargin: Style.marginS
}
NText {
Layout.fillWidth: true
visible: fullContent.length > 0
text: {
const chars = fullContent.length;
const words = fullContent.split(/\s+/).filter(w => w.length > 0).length;
const lines = fullContent.split('\n').length;
return `${chars} chars, ${words} words, ${lines} lines`;
}
pointSize: Style.fontSizeS
color: Color.mOnSurfaceVariant
}
}
}
}
+7
View File
@@ -687,6 +687,13 @@ SmartPanel {
}
}
Behavior on y {
NumberAnimation {
duration: Style.animationFast
easing.type: Easing.OutCubic
}
}
Loader {
id: previewLoader
anchors.fill: parent
@@ -228,7 +228,7 @@ Item {
}
function formatImageEntry(item) {
const meta = parseImageMeta(item.preview);
const meta = ClipboardService.parseImageMeta(item.preview);
return {
"name": meta ? `Image ${meta.w}×${meta.h}` : "Image",
@@ -283,22 +283,6 @@ Item {
};
}
function parseImageMeta(preview) {
const re = /\[\[\s*binary data\s+([\d\.]+\s*(?:KiB|MiB|GiB|B))\s+(\w+)\s+(\d+)x(\d+)\s*\]\]/i;
const match = (preview || "").match(re);
if (!match) {
return null;
}
return {
"size": match[1],
"fmt": (match[2] || "").toUpperCase(),
"w": Number(match[3]),
"h": Number(match[4])
};
}
function getImageForItem(clipboardId) {
return ClipboardService.getImageData ? ClipboardService.getImageData(clipboardId) : null;
}
+14
View File
@@ -468,4 +468,18 @@ Singleton {
revision++;
Qt.callLater(() => list());
}
// Parse image metadata from cliphist preview string
function parseImageMeta(preview) {
const re = /\[\[\s*binary data\s+([\d\.]+\s*(?:KiB|MiB|GiB|B))\s+(\w+)\s+(\d+)x(\d+)\s*\]\]/i;
const match = (preview || "").match(re);
if (!match)
return null;
return {
"size": match[1],
"fmt": (match[2] || "").toUpperCase(),
"w": Number(match[3]),
"h": Number(match[4])
};
}
}