Files

361 lines
7.7 KiB
QML

import Quickshell
import Quickshell.Services.Polkit
import Quickshell.Wayland
import Quickshell.Widgets
import ZShell.Components
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import qs.Components
import qs.Modules
import ZShell.Config
import qs.Services
Scope {
id: root
property alias polkitAgent: polkitAgent
property bool shouldShow: false
PanelWindow {
id: panelWindow
property bool detailsOpen: false
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.namespace: "ZShell-Auth"
color: "transparent"
visible: false
Connections {
function onShouldShowChanged(): void {
if (root.shouldShow) {
panelWindow.visible = true;
openAnim.start();
} else {
closeAnim.start();
}
}
target: root
}
Anim {
id: openAnim
property: "opacity"
target: inputPanel
to: 1
}
Anim {
id: closeAnim
property: "opacity"
target: inputPanel
to: 0
onFinished: {
panelWindow.visible = false;
}
onStarted: {
panelWindow.detailsOpen = false;
}
}
anchors {
bottom: true
left: true
right: true
top: true
}
// mask: Region { item: inputPanel }
Rectangle {
id: inputPanel
anchors.centerIn: parent
color: Colors.tPalette.m3surface
implicitHeight: layout.childrenRect.height + 28
implicitWidth: layout.childrenRect.width + 32
opacity: 0
radius: Tokens.rounding.small * 2
ColumnLayout {
id: layout
anchors.centerIn: parent
RowLayout {
id: contentRow
spacing: 24
Item {
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Layout.leftMargin: 16
Layout.preferredHeight: icon.implicitSize
Layout.preferredWidth: icon.implicitSize
IconImage {
id: icon
anchors.fill: parent
implicitSize: 64
mipmap: true
source: Quickshell.iconPath(polkitAgent.flow?.iconName, true) ?? ""
visible: `${source}`.includes("://")
}
MaterialIcon {
anchors.fill: parent
font.pointSize: 64
horizontalAlignment: Text.AlignHCenter
text: "security"
verticalAlignment: Text.AlignVCenter
visible: !icon.visible
}
}
ColumnLayout {
id: contentColumn
Layout.fillHeight: true
Layout.fillWidth: true
CustomText {
Layout.alignment: Qt.AlignLeft
Layout.preferredWidth: Math.min(600, contentWidth)
font.bold: true
font.pointSize: 16
text: polkitAgent.flow?.message
wrapMode: Text.WordWrap
}
CustomText {
Layout.alignment: Qt.AlignLeft
Layout.preferredWidth: Math.min(600, contentWidth)
color: Colors.tPalette.m3onSurfaceVariant
font.bold: true
font.pointSize: 12
text: polkitAgent.flow?.supplementaryMessage || "No Additional Information"
wrapMode: Text.WordWrap
}
TextField {
id: passInput
Layout.preferredHeight: 40
Layout.preferredWidth: contentColumn.implicitWidth
color: Colors.palette.m3onSurfaceVariant
echoMode: polkitAgent.flow?.responseVisible ? TextInput.Normal : TextInput.Password
placeholderText: polkitAgent.flow?.failed ? " Incorrect Password" : " Input Password"
placeholderTextColor: polkitAgent.flow?.failed ? Colors.palette.m3onError : Colors.tPalette.m3onSurfaceVariant
selectByMouse: true
background: CustomRect {
color: (polkitAgent.flow?.failed && passInput.text === "") ? Colors.palette.m3error : Colors.tPalette.m3surfaceVariant
implicitHeight: 40
radius: Tokens.rounding.smallest
}
onAccepted: okButton.clicked()
}
CustomCheckbox {
id: showPassCheckbox
Layout.alignment: Qt.AlignLeft
checked: polkitAgent.flow?.responseVisible
text: "Show Password"
onCheckedChanged: {
passInput.echoMode = checked ? TextInput.Normal : TextInput.Password;
passInput.forceActiveFocus();
}
}
}
}
CustomRect {
id: detailsPanel
property bool open: panelWindow.detailsOpen
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
clip: true
color: Colors.tPalette.m3surfaceContainerLow
implicitHeight: 0
radius: 16
visible: true
Behavior on open {
ParallelAnimation {
Anim {
property: "implicitHeight"
target: detailsPanel
to: !detailsPanel.open ? textDetailsColumn.childrenRect.height + 16 : 0
}
Anim {
property: "opacity"
target: textDetailsColumn
to: !detailsPanel.open ? 1 : 0
}
Anim {
property: "scale"
target: textDetailsColumn
to: !detailsPanel.open ? 1 : 0.9
}
}
}
ColumnLayout {
id: textDetailsColumn
anchors.fill: parent
anchors.margins: 8
opacity: 0
scale: 0.9
spacing: 8
CustomText {
text: `actionId: ${polkitAgent.flow?.actionId}`
wrapMode: Text.WordWrap
}
CustomText {
text: `selectedIdentity: ${polkitAgent.flow?.selectedIdentity}`
wrapMode: Text.WordWrap
}
}
}
RowLayout {
Layout.preferredWidth: contentRow.implicitWidth
spacing: 8
IconTextButton {
id: detailsButton
Layout.alignment: Qt.AlignLeft
icon: "info"
inactiveColor: Colors.palette.m3surfaceContainer
inactiveOnColor: Colors.palette.m3onSurface
isRound: true
shapeMorph: true
text: "Details"
onClicked: {
panelWindow.detailsOpen = !panelWindow.detailsOpen;
}
}
Item {
id: spacer
Layout.fillWidth: true
}
ButtonRow {
Layout.alignment: Qt.AlignRight
spacing: Tokens.spacing.normal
IconTextButton {
id: okButton
enabled: passInput.text.length > 0 || !!polkitAgent.flow?.isResponseRequired
horizontalPadding: Tokens.padding.large
icon: "check"
inactiveColor: Colors.palette.m3primary
inactiveOnColor: Colors.palette.m3onPrimary
isRound: true
isToggle: false
shapeMorph: true
shapeMorphExpansion: pressed ? 12 : 0
text: "OK"
onClicked: {
polkitAgent.flow.submit(passInput.text);
passInput.text = "";
passInput.forceActiveFocus();
}
}
IconTextButton {
id: cancelButton
enabled: passInput.text.length > 0 || !!polkitAgent.flow?.isResponseRequired
horizontalPadding: Tokens.padding.large
icon: "close"
inactiveColor: Colors.palette.m3surfaceContainer
inactiveOnColor: Colors.palette.m3onSurface
isRound: true
isToggle: false
shapeMorph: true
shapeMorphExpansion: pressed ? 12 : 0
text: "Cancel"
onClicked: {
root.shouldShow = false;
polkitAgent.flow.cancelAuthenticationRequest();
passInput.text = "";
}
}
}
}
}
}
Connections {
function onIsResponseRequiredChanged() {
passInput.text = "";
if (polkitAgent.flow?.isResponseRequired)
root.shouldShow = true;
passInput.forceActiveFocus();
}
function onIsSuccessfulChanged() {
if (polkitAgent.flow?.isSuccessful)
root.shouldShow = false;
passInput.text = "";
}
target: polkitAgent.flow
}
}
PolkitAgent {
id: polkitAgent
}
Variants {
model: Quickshell.screens
PanelWindow {
required property var modelData
color: root.shouldShow ? "#80000000" : "transparent"
exclusionMode: ExclusionMode.Ignore
screen: modelData
visible: panelWindow.visible
Behavior on color {
CAnim {
}
}
anchors {
bottom: true
left: true
right: true
top: true
}
}
}
}