// One row of clipboard history: what was copied, where it came from, and how // long ago. Clicking it puts the entry back on the clipboard. // // Rows are cards on an already-glass surface, so they get no prism edge — the // hairline marks a pane of glass, not every item sitting on one. import QtQuick import qs.config import qs.services Rectangle { id: root required property var entry signal activated implicitHeight: Math.max(52, body.implicitHeight + 18) radius: Theme.cardRadius // border.width: 0 works around QTBUG-137166, where transparent rounded // rectangles can render with holes at the corners. border.width: 0 color: { if (mouse.pressed) return Theme.alpha(Theme.accent, Theme.activeAlpha); if (mouse.containsMouse) return Theme.alpha(Theme.fg, Theme.hoverAlpha); return "transparent"; } // Fast in, relaxed out — the row should feel like it answers the pointer // rather than fading after it. Behavior on color { ColorAnimation { duration: mouse.containsMouse ? Theme.durFast : Theme.durNormal easing.type: Easing.OutQuad } } // Nerd Font glyph for the kind of thing that was copied. Text is the common // case and gets the quietest icon, so the odd link or image stands out. readonly property string kindGlyph: { switch (root.entry.kind) { case Clipboard.kindLink: return "\u{F0C1}"; // nf-fa-link case Clipboard.kindImage: return "\u{F03E}"; // nf-fa-picture_o case Clipboard.kindFile: return "\u{F016}"; // nf-fa-file_o default: return "\u{F15C}"; // nf-fa-file_text_o } } // Where it came from. Vicinae leaves `source` empty for clients it cannot // attribute (anything pasted by a script, for one), in which case a link's // host is more informative than nothing. readonly property string origin: root.entry.source || root.entry.host || "" Text { id: glyph anchors.left: parent.left anchors.leftMargin: 12 anchors.top: parent.top anchors.topMargin: 11 text: root.entry.encrypted ? "\u{F023}" : root.kindGlyph // fontMono is the Nerd Font, used here only to draw an icon. font.family: Theme.fontMono font.pixelSize: 14 color: root.entry.pinned ? Theme.accent : Theme.fgMuted } Column { id: body anchors.left: glyph.right anchors.leftMargin: 10 anchors.right: timeLabel.left anchors.rightMargin: 10 anchors.verticalCenter: parent.verticalCenter spacing: 3 Text { width: parent.width text: root.entry.encrypted ? "Concealed by Vicinae" : root.entry.preview color: root.entry.encrypted ? Theme.fgMuted : Theme.fg font.family: Theme.fontFamily font.pixelSize: Theme.fontSize font.italic: root.entry.encrypted wrapMode: Text.Wrap maximumLineCount: 2 elide: Text.ElideRight } Row { spacing: 6 visible: chip.visible || originLabel.visible // Images and file drags have no text worth reading, so the type is // spelled out rather than left to the glyph alone. Rectangle { id: chip visible: !root.entry.textual width: chipLabel.implicitWidth + 12 height: chipLabel.implicitHeight + 4 radius: 4 border.width: 0 color: Theme.alpha(Theme.fg, 0.10) Text { id: chipLabel anchors.centerIn: parent text: root.entry.typeLabel color: Theme.fgDim font.family: Theme.fontFamily font.pixelSize: Theme.fontSizeSmall font.weight: Font.Medium } } Text { id: originLabel anchors.verticalCenter: chip.verticalCenter visible: root.origin !== "" text: root.origin color: Theme.fgMuted font.family: Theme.fontFamily font.pixelSize: Theme.fontSizeSmall elide: Text.ElideRight } } } Row { id: timeLabel anchors.right: parent.right anchors.rightMargin: 12 anchors.top: parent.top anchors.topMargin: 11 spacing: 5 Text { anchors.verticalCenter: parent.verticalCenter visible: root.entry.pinned text: "\u{F0403}" // nf-md-pin font.family: Theme.fontMono font.pixelSize: 11 color: Theme.accent } Text { anchors.verticalCenter: parent.verticalCenter text: Clipboard.relativeTime(root.entry.ts) color: Theme.fgMuted font.family: Theme.fontFamily // The list is full of these stacked in a column; tabular figures // keep them from stepping sideways row to row. font.features: Theme.tabularFigures font.pixelSize: Theme.fontSizeSmall } } MouseArea { id: mouse anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: root.activated() } }