dots/quickshell/shell/Modules/Pass.qml
2026-02-14 17:22:42 +00:00

241 lines
7.8 KiB
QML

import Quickshell
import Quickshell.Wayland
import Quickshell.Io
import Quickshell.Widgets
import QtQuick
import Qt.labs.folderlistmodel
import QtQuick.Layouts
import QtQuick.Controls
import "../Config"
PanelWindow {
id: pass
anchors.bottom: true
property var open: false
property int selectedIndex: 0
property string passLocation: ""
function genHeight() {
if (folderModel.count > 5) {
return 6*search.height
}
else {
return (search.height * (folderModel.count + 1)) + Config.launcherOuterPadding
}
}
Process {
id: passCopy
running: false
command: ["pass", "-c", passLocation]
}
Process {
id: userCopy
running: false
command: ["pass", "-c2", passLocation]
stdout: StdioCollector {
onStreamFinished: passCopy.running = true
}
}
function goBack() {
var lastSlash = list.currentItem.filePath.lastIndexOf('/')
var currentDir = list.currentItem.filePath.substring(0, lastSlash)
var lastSlash = currentDir.lastIndexOf('/')
var parentDir = currentDir.substring(0, lastSlash)
if (currentDir == "/home/ceres/.password-store") {
return;
}
else {
folderModel.folder = "file://" + parentDir
}
}
function copyPass() {
if(list.currentItem.fileIsDir==true) {
folderModel.folder = folderModel.folder+"/"+list.currentItem.fileBaseName
}
else {
passLocation = list.currentItem.filePath
passLocation = passLocation.replace("/home/ceres/.password-store/", "")
passLocation = passLocation.replace(".gpg", "")
userCopy.running = true
pass.open = false
search.text = ""
folderModel.folder = "file:///home/ceres/.password-store"
}
}
implicitHeight: open ? genHeight() : 0
implicitWidth: HostSpecific.menuWidth
color: "transparent"
visible: open ? true : false
Behavior on implicitHeight {
NumberAnimation {
duration: 80
easing.type: Easing.InOutQuad
easing.overshoot: 2
}
}
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
exclusionMode: ExclusionMode.Ignore
Rectangle {
id: rect
anchors.fill: parent
color: Colours.background
opacity: 0.9
topLeftRadius: 20
topRightRadius: 20
ColumnLayout {
id: content
anchors.fill: parent
Row{
Rectangle {
color: "transparent"
width: Config.launcherOuterPadding
height: search.height
}
Rectangle {
height: search.height
width: search.height
color: "transparent"
IconImage {
anchors.centerIn: parent
source: Quickshell.iconPath("search-icon")
height: search.height
width: search.height
}
}
Rectangle {
color: "transparent"
width: pass.width - search.height - (2 * Config.launcherOuterPadding)
height: search.height
TextField {
id: search
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
focus: true
placeholderText: "Search..."
background: null
font.pixelSize: HostSpecific.menuFontSize
color: Colours.foreground
placeholderTextColor: Colours.colour0
font.family: "Departure Mono"
Keys.onPressed: event => {
if (event.key == Qt.Key_Return) {
copyPass();
event.accepted = true;
}
if (event.key == Qt.Key_Down) {
if(list.currentIndex<folderModel.count-1) {
list.currentIndex++;
}
event.accepted = true;
}
if (event.key == Qt.Key_Up) {
if (list.currentIndex > 0) {
list.currentIndex--;
}
event.accepted = true;
}
if (event.key == Qt.Key_Escape) {
pass.open = false;
list.currentIndex = 0
folderModel.folder = "file:///home/ceres/.password-store"
event.accepted = true;
}
if (event.key == Qt.Key_Tab) {
goBack();
event.accepted = true;
}
}
}
}
Rectangle {
color: "transparent"
width: Config.launcherOuterPadding
height: search.height
}
}
FolderListModel {
id: folderModel
folder: "file:///home/ceres/.password-store"
caseSensitive: false
showDirs: search.text === "" ? true : false
showDirsFirst: true
nameFilters: "*"+search.text+"*"
}
ListView {
id: list
model: folderModel
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
preferredHighlightBegin: 0
highlight: Rectangle { color: Colours.colour1; radius:20 }
currentIndex: 0
delegate: Row {
required property string fileBaseName
required property bool fileIsDir
required property string filePath
Rectangle {
color: "transparent"
width: Config.launcherOuterPadding
height: search.height
}
Rectangle {
color: "transparent"
height: search.height
width: pass.width - (2 * Config.launcherOuterPadding)
Text{
function genText() {
if(fileIsDir==true) {
return fileBaseName+"/"
}
else {
return fileBaseName
}
}
color: Colours.foreground
text: genText()
font.pixelSize: search.font.pixelSize
font.family: "Departure Mono"
anchors.verticalCenter: parent.verticalCenter
}
}
}
}
}
}
IpcHandler {
target: "pass"
function toggle() {
search.text = ""
pass.open = !pass.open
}
}
}