diff options
Diffstat (limited to 'modules/lock/Center.qml')
| -rw-r--r-- | modules/lock/Center.qml | 162 |
1 files changed, 159 insertions, 3 deletions
diff --git a/modules/lock/Center.qml b/modules/lock/Center.qml index 91fcf2f..4db0376 100644 --- a/modules/lock/Center.qml +++ b/modules/lock/Center.qml @@ -1,6 +1,7 @@ pragma ComponentBehavior: Bound import qs.components +import qs.components.controls import qs.components.images import qs.services import qs.config @@ -17,6 +18,7 @@ ColumnLayout { readonly property int centerWidth: Config.lock.sizes.centerWidth * centerScale Layout.preferredWidth: centerWidth + Layout.fillWidth: false Layout.fillHeight: true spacing: Appearance.spacing.large * 2 @@ -148,9 +150,34 @@ ColumnLayout { anchors.margins: Appearance.padding.small spacing: Appearance.spacing.normal - MaterialIcon { - Layout.leftMargin: Appearance.padding.smaller - text: "lock" + Item { + implicitWidth: implicitHeight + implicitHeight: fprintIcon.implicitHeight + Appearance.padding.small * 2 + + MaterialIcon { + id: fprintIcon + + anchors.centerIn: parent + animate: true + text: { + if (root.lock.pam.fprint.tries >= Config.lock.maxFprintTries) + return "fingerprint_off"; + if (root.lock.pam.fprint.active) + return "fingerprint"; + return "lock"; + } + color: root.lock.pam.fprint.tries >= Config.lock.maxFprintTries ? Colours.palette.m3error : Colours.palette.m3onSurface + opacity: root.lock.pam.passwd.active ? 0 : 1 + + Behavior on opacity { + Anim {} + } + } + + StyledBusyIndicator { + anchors.fill: parent + running: root.lock.pam.passwd.active + } } InputField { @@ -186,6 +213,135 @@ ColumnLayout { } } + StyledText { + id: message + + readonly property Pam pam: root.lock.pam + readonly property string msg: { + if (pam.fprintState === "error") + return qsTr("ERROR: %1").arg(pam.fprint.message); + if (pam.state === "error") + return qsTr("ERROR: %1").arg(pam.passwd.message); + + if (pam.lockMessage) + return pam.lockMessage; + + if (pam.state === "max" && pam.fprintState === "max") + return qsTr("Maximum password and fingerprint attempts reached."); + if (pam.state === "max") { + if (pam.fprint.available) + return qsTr("Maximum password attempts reached. Please use fingerprint."); + return qsTr("Maximum password attempts reached."); + } + if (pam.fprintState === "max") + return qsTr("Maximum fingerprint attempts reached. Please use password."); + + if (pam.state === "fail") { + if (pam.fprint.available) + return qsTr("Incorrect password. Please try again or use fingerprint."); + return qsTr("Incorrect password. Please try again."); + } + if (pam.fprintState === "fail") + return qsTr("Fingerprint not recognized (%1/%2). Please try again or use password.").arg(pam.fprint.tries).arg(Config.lock.maxFprintTries); + + return ""; + } + + Layout.fillWidth: true + Layout.topMargin: -Appearance.spacing.large + + scale: 0.7 + opacity: 0 + color: Colours.palette.m3error + + font.pointSize: Appearance.font.size.small + font.family: Appearance.font.family.mono + horizontalAlignment: Qt.AlignHCenter + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + + onMsgChanged: { + if (msg) { + if (opacity > 0) { + animate = true; + text = msg; + animate = false; + + exitAnim.stop(); + if (scale < 1) + appearAnim.restart(); + else + flashAnim.restart(); + } else { + text = msg; + exitAnim.stop(); + appearAnim.restart(); + } + } else { + appearAnim.stop(); + flashAnim.stop(); + exitAnim.start(); + } + } + + Connections { + target: root.lock.pam + + function onFlashMsg(): void { + exitAnim.stop(); + if (message.scale < 1) + appearAnim.restart(); + else + flashAnim.restart(); + } + } + + Anim { + id: appearAnim + + target: message + properties: "scale,opacity" + to: 1 + onFinished: flashAnim.restart() + } + + SequentialAnimation { + id: flashAnim + + loops: 2 + + MessageAnim { + to: 0.3 + } + MessageAnim { + to: 1 + } + } + + ParallelAnimation { + id: exitAnim + + Anim { + target: message + property: "scale" + to: 0.7 + duration: Appearance.anim.durations.large + } + Anim { + target: message + property: "opacity" + to: 0 + duration: Appearance.anim.durations.large + } + } + } + + component MessageAnim: NumberAnimation { + target: message + property: "opacity" + duration: Appearance.anim.durations.small + easing.type: Easing.Linear + } + component Anim: NumberAnimation { duration: Appearance.anim.durations.normal easing.type: Easing.BezierSpline |