1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-02-01 01:12:49 -05:00

lock screen format override

This commit is contained in:
bbedward
2025-08-12 19:25:33 -04:00
parent ac5a0fe995
commit fc1beca5e7
3 changed files with 1398 additions and 1379 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,15 @@
pragma ComponentBehavior
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Effects import QtQuick.Effects
import QtQuick.Layouts
import Quickshell import Quickshell
import Quickshell.Services.Pam
import Quickshell.Io import Quickshell.Io
import Quickshell.Services.Pam
import qs.Common import qs.Common
import qs.Modals
import qs.Services import qs.Services
import qs.Widgets import qs.Widgets
import qs.Modals pragma ComponentBehavior
Item { Item {
id: root id: root
@@ -20,35 +19,32 @@ Item {
property bool unlocking: false property bool unlocking: false
property var powerModal: null property var powerModal: null
property string confirmAction: "" property string confirmAction: ""
property var facts: ["Light takes 100,000 years to escape the Sun's core, then just 8 minutes to reach us.", "A teaspoon of neutron star matter would weigh a billion tons here on Earth.", "Right now, 100 trillion solar neutrinos are passing through your body every second.", "The Sun burns 4 million tons of itself into pure energy every second.", "The universe still glows with leftover heat from the Big Bang—just 2.7 degrees above absolute zero.", "There's a nebula out there that's actually colder than empty space itself.", "We've detected black holes crashing together by measuring spacetime stretch by less than 1/10,000th the width of a proton.", "Some cosmic radio bursts release more energy in milliseconds than our Sun does in days.", "Our galaxy might be crawling with billions of rogue planets drifting alone in the dark.", "Distant galaxies can move away from us faster than light because space itself is stretching.", "The edge of what we can see is 46.5 billion light-years away, even though the universe is only 13.8 billion years old.", "The universe is mostly invisible: 5% regular matter, 27% dark matter, 68% dark energy.", "A day on Venus lasts longer than its entire year around the Sun.", "On Mercury, the time between sunrises is 176 Earth days long.", "In about 4.5 billion years, our galaxy will smash into Andromeda.", "Most of the gold in your jewelry was forged when neutron stars collided somewhere in space.", "A black hole the mass of our Sun would take longer to evaporate than the current age of the universe... times a trillion trillion trillion trillion trillion.", "The fastest spinning star we know rotates 716 times per second.", "Cosmic rays create particles that shouldn't make it to Earth's surface, but time dilation lets them sneak through.", "Jupiter's magnetic field is so huge that if we could see it, it would look bigger than the Moon in our sky."] property var facts: ["Light takes 100,000 years to escape the Sun's core, then just 8 minutes to reach us.", "A teaspoon of neutron star matter would weigh a billion tons here on Earth.", "Right now, 100 trillion solar neutrinos are passing through your body every second.", "The Sun burns 4 million tons of itself into pure energy every second.", "The universe still glows with leftover heat from the Big Bang—just 2.7 degrees above absolute zero.", "There's a nebula out there that's actually colder than empty space itself.", "We've detected black holes crashing together by measuring spacetime stretch by less than 1/10,000th the width of a proton.", "Some cosmic radio bursts release more energy in milliseconds than our Sun does in days.", "Our galaxy might be crawling with billions of rogue planets drifting alone in the dark.", "Distant galaxies can move away from us faster than light because space itself is stretching.", "The edge of what we can see is 46.5 billion light-years away, even though the universe is only 13.8 billion years old.", "The universe is mostly invisible: 5% regular matter, 27% dark matter, 68% dark energy.", "A day on Venus lasts longer than its entire year around the Sun.", "On Mercury, the time between sunrises is 176 Earth days long.", "In about 4.5 billion years, our galaxy will smash into Andromeda.", "Most of the gold in your jewelry was forged when neutron stars collided somewhere in space.", "A black hole the mass of our Sun would take longer to evaporate than the current age of the universe... times a trillion trillion trillion trillion trillion.", "The fastest spinning star we know rotates 716 times per second.", "Cosmic rays create particles that shouldn't make it to Earth's surface, but time dilation lets them sneak through.", "Jupiter's magnetic field is so huge that if we could see it, it would look bigger than the Moon in our sky."]
property string randomFact: "" property string randomFact: ""
signal unlockRequested signal unlockRequested()
Component.onCompleted: {
pickRandomFact()
WeatherService.addRef()
UserInfoService.refreshUserInfo()
}
function pickRandomFact() { function pickRandomFact() {
randomFact = facts[Math.floor(Math.random() * facts.length)] randomFact = facts[Math.floor(Math.random() * facts.length)];
} }
Component.onCompleted: {
pickRandomFact();
WeatherService.addRef();
UserInfoService.refreshUserInfo();
}
onDemoModeChanged: { onDemoModeChanged: {
if (demoMode) { if (demoMode)
pickRandomFact() pickRandomFact();
}
}
}
Component.onDestruction: { Component.onDestruction: {
WeatherService.removeRef() WeatherService.removeRef();
} }
Image { Image {
id: wallpaperBackground id: wallpaperBackground
anchors.fill: parent anchors.fill: parent
source: SessionData.wallpaperPath || "" source: SessionData.wallpaperPath || ""
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
@@ -56,14 +52,14 @@ Item {
asynchronous: true asynchronous: true
cache: true cache: true
visible: source !== "" visible: source !== ""
layer.enabled: true layer.enabled: true
layer.effect: MultiEffect { layer.effect: MultiEffect {
autoPaddingEnabled: false autoPaddingEnabled: false
blurEnabled: true blurEnabled: true
blur: 0.8 blur: 0.8
blurMax: 32 blurMax: 32
blurMultiplier: 1.0 blurMultiplier: 1
} }
Behavior on opacity { Behavior on opacity {
@@ -71,7 +67,9 @@ Item {
duration: Theme.mediumDuration duration: Theme.mediumDuration
easing.type: Theme.standardEasing easing.type: Theme.standardEasing
} }
} }
} }
Rectangle { Rectangle {
@@ -82,6 +80,7 @@ Item {
SystemClock { SystemClock {
id: systemClock id: systemClock
precision: SystemClock.Seconds precision: SystemClock.Seconds
} }
@@ -97,12 +96,10 @@ Item {
StyledText { StyledText {
id: clockText id: clockText
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top anchors.top: parent.top
text: SettingsData.use24HourClock ? Qt.formatTime( text: SettingsData.use24HourClock ? Qt.formatTime(systemClock.date, "H:mm") : Qt.formatTime(systemClock.date, "h:mm AP")
systemClock.date,
"H:mm") : Qt.formatTime(
systemClock.date, "h:mm AP")
font.pixelSize: 120 font.pixelSize: 120
font.weight: Font.Light font.weight: Font.Light
color: "white" color: "white"
@@ -113,11 +110,12 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: clockText.bottom anchors.top: clockText.bottom
anchors.topMargin: -20 anchors.topMargin: -20
text: Qt.formatDate(new Date(), "dddd, MMMM d") text: Qt.formatDate(systemClock.date, SettingsData.lockDateFormat)
font.pixelSize: Theme.fontSizeXLarge font.pixelSize: Theme.fontSizeXLarge
color: "white" color: "white"
opacity: 0.9 opacity: 0.9
} }
} }
ColumnLayout { ColumnLayout {
@@ -132,9 +130,11 @@ Item {
Item { Item {
id: avatarContainer id: avatarContainer
property bool hasImage: profileImageLoader.status === Image.Ready
Layout.preferredWidth: 60 Layout.preferredWidth: 60
Layout.preferredHeight: 60 Layout.preferredHeight: 60
property bool hasImage: profileImageLoader.status === Image.Ready
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
@@ -147,12 +147,15 @@ Item {
Image { Image {
id: profileImageLoader id: profileImageLoader
source: { source: {
if (PortalService.profileImage === "") if (PortalService.profileImage === "")
return "" return "";
if (PortalService.profileImage.startsWith("/")) if (PortalService.profileImage.startsWith("/"))
return "file://" + PortalService.profileImage return "file://" + PortalService.profileImage;
return PortalService.profileImage
return PortalService.profileImage;
} }
smooth: true smooth: true
asynchronous: true asynchronous: true
@@ -174,6 +177,7 @@ Item {
Item { Item {
id: circularMask id: circularMask
width: 60 - 10 width: 60 - 10
height: 60 - 10 height: 60 - 10
layer.enabled: true layer.enabled: true
@@ -186,6 +190,7 @@ Item {
color: "black" color: "black"
antialiasing: true antialiasing: true
} }
} }
Rectangle { Rectangle {
@@ -200,6 +205,7 @@ Item {
size: Theme.iconSize + 4 size: Theme.iconSize + 4
color: Theme.primaryText color: Theme.primaryText
} }
} }
DankIcon { DankIcon {
@@ -207,32 +213,24 @@ Item {
name: "warning" name: "warning"
size: Theme.iconSize + 4 size: Theme.iconSize + 4
color: Theme.primaryText color: Theme.primaryText
visible: PortalService.profileImage !== "" visible: PortalService.profileImage !== "" && profileImageLoader.status === Image.Error
&& profileImageLoader.status === Image.Error
} }
} }
Rectangle { Rectangle {
property bool showPassword: false
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 60 Layout.preferredHeight: 60
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.9)
Theme.surfaceContainer.b, 0.9) border.color: passwordField.activeFocus ? Theme.primary : Qt.rgba(1, 1, 1, 0.3)
border.color: passwordField.activeFocus ? Theme.primary : Qt.rgba(
1, 1, 1, 0.3)
border.width: passwordField.activeFocus ? 2 : 1 border.width: passwordField.activeFocus ? 2 : 1
property bool showPassword: false
Behavior on border.color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
DankIcon { DankIcon {
id: lockIcon id: lockIcon
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: Theme.spacingM anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -243,69 +241,68 @@ Item {
TextInput { TextInput {
id: passwordField id: passwordField
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: lockIcon.width + Theme.spacingM * 2 anchors.leftMargin: lockIcon.width + Theme.spacingM * 2
anchors.rightMargin: (revealButton.visible ? revealButton.width + Theme.spacingM : 0) anchors.rightMargin: (revealButton.visible ? revealButton.width + Theme.spacingM : 0) + (enterButton.visible ? enterButton.width + Theme.spacingM : 0) + (loadingSpinner.visible ? loadingSpinner.width + Theme.spacingM : Theme.spacingM)
+ (enterButton.visible ? enterButton.width + Theme.spacingM : 0)
+ (loadingSpinner.visible ? loadingSpinner.width
+ Theme.spacingM : Theme.spacingM)
opacity: 0 opacity: 0
focus: !demoMode focus: !demoMode
enabled: !demoMode enabled: !demoMode
echoMode: parent.showPassword ? TextInput.Normal : TextInput.Password echoMode: parent.showPassword ? TextInput.Normal : TextInput.Password
onTextChanged: {
if (!demoMode)
root.passwordBuffer = text;
}
onAccepted: {
if (!demoMode && root.passwordBuffer.length > 0 && !pam.active) {
console.log("Enter pressed, starting PAM authentication");
pam.start();
}
}
Keys.onPressed: (event) => {
if (demoMode)
return ;
if (pam.active) {
console.log("PAM is active, ignoring input");
event.accepted = true;
return ;
}
}
Timer { Timer {
id: focusTimer id: focusTimer
interval: 100 interval: 100
running: !demoMode running: !demoMode
onTriggered: passwordField.forceActiveFocus() onTriggered: passwordField.forceActiveFocus()
} }
onTextChanged: {
if (!demoMode) {
root.passwordBuffer = text
}
}
onAccepted: {
if (!demoMode && root.passwordBuffer.length > 0 && !pam.active) {
console.log("Enter pressed, starting PAM authentication")
pam.start()
}
}
Keys.onPressed: event => {
if (demoMode)
return
if (pam.active) {
console.log("PAM is active, ignoring input")
event.accepted = true
return
}
}
} }
StyledText { StyledText {
id: placeholder id: placeholder
property string pamState: ""
anchors.left: lockIcon.right anchors.left: lockIcon.right
anchors.leftMargin: Theme.spacingM anchors.leftMargin: Theme.spacingM
anchors.right: (revealButton.visible ? revealButton.left : (enterButton.visible ? enterButton.left : (loadingSpinner.visible ? loadingSpinner.left : parent.right))) anchors.right: (revealButton.visible ? revealButton.left : (enterButton.visible ? enterButton.left : (loadingSpinner.visible ? loadingSpinner.left : parent.right)))
anchors.rightMargin: Theme.spacingS anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
property string pamState: ""
text: { text: {
if (demoMode) if (demoMode)
return "" return "";
if (root.unlocking)
return "Unlocking..."
if (pam.active)
return "Authenticating..."
return "hunter2"
}
if (root.unlocking)
return "Unlocking...";
if (pam.active)
return "Authenticating...";
return "hunter2";
}
color: root.unlocking ? Theme.primary : (pam.active ? Theme.primary : Theme.outline) color: root.unlocking ? Theme.primary : (pam.active ? Theme.primary : Theme.outline)
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
opacity: (demoMode || root.passwordBuffer.length === 0) ? 1 : 0 opacity: (demoMode || root.passwordBuffer.length === 0) ? 1 : 0
@@ -315,6 +312,7 @@ Item {
duration: Theme.mediumDuration duration: Theme.mediumDuration
easing.type: Theme.standardEasing easing.type: Theme.standardEasing
} }
} }
Behavior on color { Behavior on color {
@@ -322,7 +320,9 @@ Item {
duration: Theme.shortDuration duration: Theme.shortDuration
easing.type: Theme.standardEasing easing.type: Theme.standardEasing
} }
} }
} }
StyledText { StyledText {
@@ -331,17 +331,14 @@ Item {
anchors.right: (revealButton.visible ? revealButton.left : (enterButton.visible ? enterButton.left : (loadingSpinner.visible ? loadingSpinner.left : parent.right))) anchors.right: (revealButton.visible ? revealButton.left : (enterButton.visible ? enterButton.left : (loadingSpinner.visible ? loadingSpinner.left : parent.right)))
anchors.rightMargin: Theme.spacingS anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: { text: {
if (demoMode) { if (demoMode)
return "••••••••" return "••••••••";
} else if (parent.showPassword) { else if (parent.showPassword)
return root.passwordBuffer return root.passwordBuffer;
} else { else
return "•".repeat(Math.min(root.passwordBuffer.length, 25)) return "•".repeat(Math.min(root.passwordBuffer.length, 25));
} }
}
color: Theme.surfaceText color: Theme.surfaceText
font.pixelSize: parent.showPassword ? Theme.fontSizeMedium : Theme.fontSizeLarge font.pixelSize: parent.showPassword ? Theme.fontSizeMedium : Theme.fontSizeLarge
opacity: (demoMode || root.passwordBuffer.length > 0) ? 1 : 0 opacity: (demoMode || root.passwordBuffer.length > 0) ? 1 : 0
@@ -352,24 +349,27 @@ Item {
duration: Theme.mediumDuration duration: Theme.mediumDuration
easing.type: Theme.standardEasing easing.type: Theme.standardEasing
} }
} }
} }
DankActionButton { DankActionButton {
id: revealButton id: revealButton
anchors.right: enterButton.visible ? enterButton.left : (loadingSpinner.visible ? loadingSpinner.left : parent.right) anchors.right: enterButton.visible ? enterButton.left : (loadingSpinner.visible ? loadingSpinner.left : parent.right)
anchors.rightMargin: Theme.spacingS anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
iconName: parent.showPassword ? "visibility_off" : "visibility" iconName: parent.showPassword ? "visibility_off" : "visibility"
buttonSize: 32 buttonSize: 32
visible: !demoMode && root.passwordBuffer.length > 0 && !pam.active visible: !demoMode && root.passwordBuffer.length > 0 && !pam.active && !root.unlocking
&& !root.unlocking
enabled: visible enabled: visible
onClicked: parent.showPassword = !parent.showPassword onClicked: parent.showPassword = !parent.showPassword
} }
Rectangle { Rectangle {
id: loadingSpinner id: loadingSpinner
anchors.right: enterButton.visible ? enterButton.left : parent.right anchors.right: enterButton.visible ? enterButton.left : parent.right
anchors.rightMargin: Theme.spacingM anchors.rightMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -388,6 +388,7 @@ Item {
SequentialAnimation on scale { SequentialAnimation on scale {
running: root.unlocking running: root.unlocking
NumberAnimation { NumberAnimation {
from: 0 from: 0
to: 1.2 to: 1.2
@@ -395,6 +396,7 @@ Item {
easing.type: Easing.BezierSpline easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.emphasizedDecel easing.bezierCurve: Anims.emphasizedDecel
} }
NumberAnimation { NumberAnimation {
from: 1.2 from: 1.2
to: 1 to: 1
@@ -402,7 +404,9 @@ Item {
easing.type: Easing.BezierSpline easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.emphasizedAccel easing.bezierCurve: Anims.emphasizedAccel
} }
} }
} }
Item { Item {
@@ -415,8 +419,7 @@ Item {
radius: 10 radius: 10
anchors.centerIn: parent anchors.centerIn: parent
color: "transparent" color: "transparent"
border.color: Qt.rgba(Theme.primary.r, Theme.primary.g, border.color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3)
Theme.primary.b, 0.3)
border.width: 2 border.width: 2
} }
@@ -434,9 +437,7 @@ Item {
height: parent.height / 2 height: parent.height / 2
anchors.top: parent.top anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
color: Qt.rgba(Theme.surfaceContainer.r, color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.9)
Theme.surfaceContainer.g,
Theme.surfaceContainer.b, 0.9)
} }
RotationAnimation on rotation { RotationAnimation on rotation {
@@ -446,24 +447,27 @@ Item {
from: 0 from: 0
to: 360 to: 360
} }
} }
} }
} }
DankActionButton { DankActionButton {
id: enterButton id: enterButton
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Theme.spacingS anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
iconName: "keyboard_return" iconName: "keyboard_return"
buttonSize: 36 buttonSize: 36
visible: (demoMode || (root.passwordBuffer.length > 0 && !pam.active visible: (demoMode || (root.passwordBuffer.length > 0 && !pam.active && !root.unlocking))
&& !root.unlocking))
enabled: !demoMode enabled: !demoMode
onClicked: { onClicked: {
if (!demoMode) { if (!demoMode) {
console.log("Enter button clicked, starting PAM authentication") console.log("Enter button clicked, starting PAM authentication");
pam.start() pam.start();
} }
} }
@@ -472,9 +476,21 @@ Item {
duration: Theme.shortDuration duration: Theme.shortDuration
easing.type: Theme.standardEasing easing.type: Theme.standardEasing
} }
} }
} }
Behavior on border.color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
} }
}
}
} }
StyledText { StyledText {
@@ -482,12 +498,15 @@ Item {
Layout.preferredHeight: placeholder.pamState ? 20 : 0 Layout.preferredHeight: placeholder.pamState ? 20 : 0
text: { text: {
if (placeholder.pamState === "error") if (placeholder.pamState === "error")
return "Authentication error - try again" return "Authentication error - try again";
if (placeholder.pamState === "max") if (placeholder.pamState === "max")
return "Too many attempts - locked out" return "Too many attempts - locked out";
if (placeholder.pamState === "fail") if (placeholder.pamState === "fail")
return "Incorrect password - try again" return "Incorrect password - try again";
return ""
return "";
} }
color: Theme.error color: Theme.error
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
@@ -500,6 +519,7 @@ Item {
duration: Theme.shortDuration duration: Theme.shortDuration
easing.type: Theme.standardEasing easing.type: Theme.standardEasing
} }
} }
Behavior on Layout.preferredHeight { Behavior on Layout.preferredHeight {
@@ -507,8 +527,11 @@ Item {
duration: Theme.shortDuration duration: Theme.shortDuration
easing.type: Theme.standardEasing easing.type: Theme.standardEasing
} }
} }
} }
} }
StyledText { StyledText {
@@ -526,8 +549,7 @@ Item {
anchors.top: parent.top anchors.top: parent.top
anchors.right: parent.right anchors.right: parent.right
anchors.margins: Theme.spacingXL anchors.margins: Theme.spacingXL
text: WeatherService.weather.available && WeatherService.weather.city text: WeatherService.weather.available && WeatherService.weather.city && WeatherService.weather.city !== "Unknown" ? `${WeatherService.weather.city} ${(SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp)}°${(SettingsData.useFahrenheit ? "F" : "C")}` : ""
&& WeatherService.weather.city !== "Unknown" ? `${WeatherService.weather.city} ${(SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp)}°${(SettingsData.useFahrenheit ? "F" : "C")}` : ""
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
color: "white" color: "white"
horizontalAlignment: Text.AlignRight horizontalAlignment: Text.AlignRight
@@ -555,11 +577,10 @@ Item {
iconColor: Theme.error iconColor: Theme.error
buttonSize: 40 buttonSize: 40
onClicked: { onClicked: {
if (demoMode) { if (demoMode)
console.log("Demo: Power") console.log("Demo: Power");
} else { else
powerDialog.open() powerDialog.open();
}
} }
} }
@@ -567,11 +588,10 @@ Item {
iconName: "refresh" iconName: "refresh"
buttonSize: 40 buttonSize: 40
onClicked: { onClicked: {
if (demoMode) { if (demoMode)
console.log("Demo: Reboot") console.log("Demo: Reboot");
} else { else
rebootDialog.open() rebootDialog.open();
}
} }
} }
@@ -579,13 +599,13 @@ Item {
iconName: "logout" iconName: "logout"
buttonSize: 40 buttonSize: 40
onClicked: { onClicked: {
if (demoMode) { if (demoMode)
console.log("Demo: Logout") console.log("Demo: Logout");
} else { else
logoutDialog.open() logoutDialog.open();
}
} }
} }
} }
StyledText { StyledText {
@@ -601,56 +621,58 @@ Item {
wrapMode: Text.NoWrap wrapMode: Text.NoWrap
visible: randomFact !== "" visible: randomFact !== ""
} }
} }
FileView { FileView {
id: pamConfigWatcher id: pamConfigWatcher
path: "/etc/pam.d/dankshell" path: "/etc/pam.d/dankshell"
printErrors: false printErrors: false
} }
PamContext { PamContext {
id: pam id: pam
config: pamConfigWatcher.loaded ? "dankshell" : "login"
config: pamConfigWatcher.loaded ? "dankshell" : "login"
onResponseRequiredChanged: { onResponseRequiredChanged: {
if (demoMode) if (demoMode)
return return ;
console.log("PAM response required:", responseRequired)
console.log("PAM response required:", responseRequired);
if (!responseRequired) if (!responseRequired)
return return ;
console.log("Responding to PAM with password buffer length:",
root.passwordBuffer.length)
respond(root.passwordBuffer)
}
onCompleted: res => { console.log("Responding to PAM with password buffer length:", root.passwordBuffer.length);
respond(root.passwordBuffer);
}
onCompleted: (res) => {
if (demoMode) if (demoMode)
return return ;
console.log("PAM authentication completed with result:", res)
console.log("PAM authentication completed with result:", res);
if (res === PamResult.Success) { if (res === PamResult.Success) {
console.log("Authentication successful, unlocking") console.log("Authentication successful, unlocking");
root.unlocking = true root.unlocking = true;
passwordField.text = "" passwordField.text = "";
root.passwordBuffer = "" root.passwordBuffer = "";
root.unlockRequested() root.unlockRequested();
return return ;
} }
console.log("Authentication failed:", res);
console.log("Authentication failed:", res)
if (res === PamResult.Error) if (res === PamResult.Error)
placeholder.pamState = "error" placeholder.pamState = "error";
else if (res === PamResult.MaxTries) else if (res === PamResult.MaxTries)
placeholder.pamState = "max" placeholder.pamState = "max";
else if (res === PamResult.Failed) else if (res === PamResult.Failed)
placeholder.pamState = "fail" placeholder.pamState = "fail";
placeholderDelay.restart();
placeholderDelay.restart()
} }
} }
Timer { Timer {
id: placeholderDelay id: placeholderDelay
interval: 4000 interval: 4000
onTriggered: placeholder.pamState = "" onTriggered: placeholder.pamState = ""
} }
@@ -663,18 +685,20 @@ Item {
Rectangle { Rectangle {
id: powerDialog id: powerDialog
function open() {
visible = true;
}
function close() {
visible = false;
}
anchors.fill: parent anchors.fill: parent
color: Qt.rgba(0, 0, 0, 0.8) color: Qt.rgba(0, 0, 0, 0.8)
visible: false visible: false
z: 1000 z: 1000
function open() {
visible = true
}
function close() {
visible = false
}
Rectangle { Rectangle {
anchors.centerIn: parent anchors.centerIn: parent
width: 320 width: 320
@@ -711,11 +735,7 @@ Item {
width: 100 width: 100
height: 40 height: 40
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: cancelMouse1.pressed ? Qt.rgba( color: cancelMouse1.pressed ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.7) : cancelMouse1.containsMouse ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.9) : Theme.surfaceVariant
Theme.surfaceVariant.r,
Theme.surfaceVariant.g,
Theme.surfaceVariant.b,
0.7) : cancelMouse1.containsMouse ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.9) : Theme.surfaceVariant
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
@@ -726,25 +746,20 @@ Item {
MouseArea { MouseArea {
id: cancelMouse1 id: cancelMouse1
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: powerDialog.close() onClicked: powerDialog.close()
} }
} }
Rectangle { Rectangle {
width: 100 width: 100
height: 40 height: 40
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: powerMouse.pressed ? Qt.rgba( color: powerMouse.pressed ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.8) : powerMouse.containsMouse ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 1) : Theme.error
Theme.error.r, Theme.error.g,
Theme.error.b,
0.8) : powerMouse.containsMouse ? Qt.rgba(
Theme.error.r,
Theme.error.g,
Theme.error.b,
1.0) : Theme.error
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
@@ -756,34 +771,42 @@ Item {
MouseArea { MouseArea {
id: powerMouse id: powerMouse
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
powerDialog.close() powerDialog.close();
Quickshell.execDetached(["systemctl", "poweroff"]) Quickshell.execDetached(["systemctl", "poweroff"]);
} }
} }
} }
} }
} }
} }
} }
Rectangle { Rectangle {
id: rebootDialog id: rebootDialog
function open() {
visible = true;
}
function close() {
visible = false;
}
anchors.fill: parent anchors.fill: parent
color: Qt.rgba(0, 0, 0, 0.8) color: Qt.rgba(0, 0, 0, 0.8)
visible: false visible: false
z: 1000 z: 1000
function open() {
visible = true
}
function close() {
visible = false
}
Rectangle { Rectangle {
anchors.centerIn: parent anchors.centerIn: parent
width: 320 width: 320
@@ -820,11 +843,7 @@ Item {
width: 100 width: 100
height: 40 height: 40
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: cancelMouse2.pressed ? Qt.rgba( color: cancelMouse2.pressed ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.7) : cancelMouse2.containsMouse ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.9) : Theme.surfaceVariant
Theme.surfaceVariant.r,
Theme.surfaceVariant.g,
Theme.surfaceVariant.b,
0.7) : cancelMouse2.containsMouse ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.9) : Theme.surfaceVariant
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
@@ -835,25 +854,20 @@ Item {
MouseArea { MouseArea {
id: cancelMouse2 id: cancelMouse2
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: rebootDialog.close() onClicked: rebootDialog.close()
} }
} }
Rectangle { Rectangle {
width: 100 width: 100
height: 40 height: 40
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: rebootMouse.pressed ? Qt.rgba( color: rebootMouse.pressed ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.8) : rebootMouse.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 1) : Theme.primary
Theme.primary.r, Theme.primary.g,
Theme.primary.b,
0.8) : rebootMouse.containsMouse ? Qt.rgba(
Theme.primary.r,
Theme.primary.g,
Theme.primary.b,
1.0) : Theme.primary
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
@@ -865,34 +879,42 @@ Item {
MouseArea { MouseArea {
id: rebootMouse id: rebootMouse
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
rebootDialog.close() rebootDialog.close();
Quickshell.execDetached(["systemctl", "reboot"]) Quickshell.execDetached(["systemctl", "reboot"]);
} }
} }
} }
} }
} }
} }
} }
Rectangle { Rectangle {
id: logoutDialog id: logoutDialog
function open() {
visible = true;
}
function close() {
visible = false;
}
anchors.fill: parent anchors.fill: parent
color: Qt.rgba(0, 0, 0, 0.8) color: Qt.rgba(0, 0, 0, 0.8)
visible: false visible: false
z: 1000 z: 1000
function open() {
visible = true
}
function close() {
visible = false
}
Rectangle { Rectangle {
anchors.centerIn: parent anchors.centerIn: parent
width: 320 width: 320
@@ -929,11 +951,7 @@ Item {
width: 100 width: 100
height: 40 height: 40
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: cancelMouse3.pressed ? Qt.rgba( color: cancelMouse3.pressed ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.7) : cancelMouse3.containsMouse ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.9) : Theme.surfaceVariant
Theme.surfaceVariant.r,
Theme.surfaceVariant.g,
Theme.surfaceVariant.b,
0.7) : cancelMouse3.containsMouse ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.9) : Theme.surfaceVariant
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
@@ -944,25 +962,20 @@ Item {
MouseArea { MouseArea {
id: cancelMouse3 id: cancelMouse3
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: logoutDialog.close() onClicked: logoutDialog.close()
} }
} }
Rectangle { Rectangle {
width: 100 width: 100
height: 40 height: 40
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: logoutMouse.pressed ? Qt.rgba( color: logoutMouse.pressed ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.8) : logoutMouse.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 1) : Theme.primary
Theme.primary.r, Theme.primary.g,
Theme.primary.b,
0.8) : logoutMouse.containsMouse ? Qt.rgba(
Theme.primary.r,
Theme.primary.g,
Theme.primary.b,
1.0) : Theme.primary
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
@@ -974,17 +987,24 @@ Item {
MouseArea { MouseArea {
id: logoutMouse id: logoutMouse
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
logoutDialog.close() logoutDialog.close();
NiriService.quit() NiriService.quit();
} }
} }
} }
} }
} }
} }
} }
} }

View File

@@ -98,7 +98,7 @@ Item {
DankDropdown { DankDropdown {
width: parent.width width: parent.width
height: 50 height: 50
text: "Format" text: "Top Bar Format"
description: "Preview: " + Qt.formatDate(new Date(), SettingsData.clockDateFormat) description: "Preview: " + Qt.formatDate(new Date(), SettingsData.clockDateFormat)
currentValue: { currentValue: {
// Find matching preset or show "Custom" // Find matching preset or show "Custom"
@@ -153,12 +153,70 @@ Item {
} }
} }
DankDropdown {
width: parent.width
height: 50
text: "Lock Screen Format"
description: "Preview: " + Qt.formatDate(new Date(), SettingsData.lockDateFormat)
currentValue: {
// Find matching preset or show "Custom"
const presets = [{
"format": "ddd d",
"label": "Day Date"
}, {
"format": "ddd MMM d",
"label": "Day Month Date"
}, {
"format": "MMM d",
"label": "Month Date"
}, {
"format": "M/d",
"label": "Numeric (M/D)"
}, {
"format": "d/M",
"label": "Numeric (D/M)"
}, {
"format": "ddd d MMM yyyy",
"label": "Full with Year"
}, {
"format": "yyyy-MM-dd",
"label": "ISO Date"
}, {
"format": "dddd, MMMM d",
"label": "Full Day & Month"
}];
const match = presets.find((p) => {
return p.format === SettingsData.lockDateFormat;
});
return match ? match.label : "Custom: " + SettingsData.lockDateFormat;
}
options: ["Day Date", "Day Month Date", "Month Date", "Numeric (M/D)", "Numeric (D/M)", "Full with Year", "ISO Date", "Full Day & Month", "Custom..."]
onValueChanged: (value) => {
const formatMap = {
"Day Date": "ddd d",
"Day Month Date": "ddd MMM d",
"Month Date": "MMM d",
"Numeric (M/D)": "M/d",
"Numeric (D/M)": "d/M",
"Full with Year": "ddd d MMM yyyy",
"ISO Date": "yyyy-MM-dd",
"Full Day & Month": "dddd, MMMM d"
};
if (value === "Custom...") {
customLockFormatInput.visible = true;
} else {
customLockFormatInput.visible = false;
SettingsData.setLockDateFormat(formatMap[value]);
}
}
}
DankTextField { DankTextField {
id: customFormatInput id: customFormatInput
width: parent.width width: parent.width
visible: false visible: false
placeholderText: "Enter custom format (e.g., ddd MMM d)" placeholderText: "Enter custom top bar format (e.g., ddd MMM d)"
text: SettingsData.clockDateFormat text: SettingsData.clockDateFormat
onTextChanged: { onTextChanged: {
if (visible && text) if (visible && text)
@@ -167,6 +225,20 @@ Item {
} }
} }
DankTextField {
id: customLockFormatInput
width: parent.width
visible: false
placeholderText: "Enter custom lock screen format (e.g., dddd, MMMM d)"
text: SettingsData.lockDateFormat
onTextChanged: {
if (visible && text)
SettingsData.setLockDateFormat(text);
}
}
Rectangle { Rectangle {
width: parent.width width: parent.width
height: formatHelp.implicitHeight + Theme.spacingM * 2 height: formatHelp.implicitHeight + Theme.spacingM * 2