mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-07 19:59:14 -04:00
feat(Greeter): Enhance login experience & manual username fallback support
This commit is contained in:
@@ -63,8 +63,11 @@ Item {
|
|||||||
readonly property bool greeterExternalAuthAvailable: (greeterPamHasFprint && GreetdSettings.greeterEnableFprint) || (greeterPamHasU2f && GreetdSettings.greeterEnableU2f)
|
readonly property bool greeterExternalAuthAvailable: (greeterPamHasFprint && GreetdSettings.greeterEnableFprint) || (greeterPamHasU2f && GreetdSettings.greeterEnableU2f)
|
||||||
readonly property bool greeterPamHasExternalAuth: greeterPamHasFprint || greeterPamHasU2f
|
readonly property bool greeterPamHasExternalAuth: greeterPamHasFprint || greeterPamHasU2f
|
||||||
readonly property bool multipleUsersAvailable: GreeterUsersService.loaded && GreeterUsersService.users.length > 1
|
readonly property bool multipleUsersAvailable: GreeterUsersService.loaded && GreeterUsersService.users.length > 1
|
||||||
readonly property bool showUserPicker: multipleUsersAvailable && !GreeterState.showPasswordInput
|
readonly property bool showUserPicker: multipleUsersAvailable && !GreeterState.showPasswordInput && !manualUsernameEntry
|
||||||
|
readonly property bool showAccountSwitchLink: multipleUsersAvailable && !GreeterState.showPasswordInput && !GreeterState.unlocking
|
||||||
|
readonly property int userPickerMaxHeight: Math.min(400, Math.max(120, height * 0.35))
|
||||||
property bool userListOpen: false
|
property bool userListOpen: false
|
||||||
|
property bool manualUsernameEntry: false
|
||||||
property bool skipAutoSelectUser: false
|
property bool skipAutoSelectUser: false
|
||||||
property string pickerThemeUsername: ""
|
property string pickerThemeUsername: ""
|
||||||
|
|
||||||
@@ -454,9 +457,34 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function enterManualUsernameEntry() {
|
||||||
|
if (!root.multipleUsersAvailable || GreeterState.showPasswordInput)
|
||||||
|
return;
|
||||||
|
root.manualUsernameEntry = true;
|
||||||
|
root.userListOpen = false;
|
||||||
|
GreeterState.username = "";
|
||||||
|
GreeterState.usernameInput = "";
|
||||||
|
GreeterState.selectedUserIndex = -1;
|
||||||
|
inputField.text = "";
|
||||||
|
root.applyPickerPreviewTheme();
|
||||||
|
Qt.callLater(() => inputField.forceActiveFocus());
|
||||||
|
}
|
||||||
|
|
||||||
|
function returnToUserListFromManualEntry() {
|
||||||
|
if (!root.multipleUsersAvailable)
|
||||||
|
return;
|
||||||
|
root.manualUsernameEntry = false;
|
||||||
|
root.userListOpen = true;
|
||||||
|
GreeterState.username = "";
|
||||||
|
GreeterState.usernameInput = "";
|
||||||
|
inputField.text = "";
|
||||||
|
root.applyPickerPreviewTheme();
|
||||||
|
}
|
||||||
|
|
||||||
function returnToUserPicker() {
|
function returnToUserPicker() {
|
||||||
if (!root.multipleUsersAvailable || GreeterState.unlocking)
|
if (!root.multipleUsersAvailable || GreeterState.unlocking)
|
||||||
return;
|
return;
|
||||||
|
root.manualUsernameEntry = false;
|
||||||
root.skipAutoSelectUser = true;
|
root.skipAutoSelectUser = true;
|
||||||
awaitingExternalAuth = false;
|
awaitingExternalAuth = false;
|
||||||
pendingPasswordResponse = false;
|
pendingPasswordResponse = false;
|
||||||
@@ -483,6 +511,7 @@ Item {
|
|||||||
const user = (rawValue || "").trim();
|
const user = (rawValue || "").trim();
|
||||||
if (!user)
|
if (!user)
|
||||||
return;
|
return;
|
||||||
|
root.manualUsernameEntry = false;
|
||||||
root.skipAutoSelectUser = false;
|
root.skipAutoSelectUser = false;
|
||||||
submitUsername(user, skipDropdownUpdate === true);
|
submitUsername(user, skipDropdownUpdate === true);
|
||||||
}
|
}
|
||||||
@@ -1025,6 +1054,8 @@ Item {
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
if (GreeterState.showPasswordInput)
|
if (GreeterState.showPasswordInput)
|
||||||
root.returnToUserPicker();
|
root.returnToUserPicker();
|
||||||
|
else if (root.manualUsernameEntry)
|
||||||
|
root.returnToUserListFromManualEntry();
|
||||||
else
|
else
|
||||||
root.userListOpen = !root.userListOpen;
|
root.userListOpen = !root.userListOpen;
|
||||||
}
|
}
|
||||||
@@ -1050,6 +1081,7 @@ Item {
|
|||||||
anchors.verticalCenter: root.userListOpen ? undefined : parent.verticalCenter
|
anchors.verticalCenter: root.userListOpen ? undefined : parent.verticalCenter
|
||||||
anchors.top: root.userListOpen ? parent.top : undefined
|
anchors.top: root.userListOpen ? parent.top : undefined
|
||||||
anchors.margins: Theme.spacingM
|
anchors.margins: Theme.spacingM
|
||||||
|
maxExpandedHeight: root.userPickerMaxHeight
|
||||||
visible: root.showUserPicker && !GreeterState.showPasswordInput
|
visible: root.showUserPicker && !GreeterState.showPasswordInput
|
||||||
expanded: root.userListOpen
|
expanded: root.userListOpen
|
||||||
onUserSelected: username => root.selectUser(username, false)
|
onUserSelected: username => root.selectUser(username, false)
|
||||||
@@ -1291,6 +1323,36 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: root.showAccountSwitchLink ? 28 : 0
|
||||||
|
visible: root.showAccountSwitchLink
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: accountSwitchLabel
|
||||||
|
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
text: root.manualUsernameEntry ? I18n.tr("Back to user list", "greeter link to return from manual username entry to user picker") : I18n.tr("Not listed?", "greeter link to switch to manual username entry")
|
||||||
|
color: Theme.primary
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.underline: accountSwitchMouse.containsMouse
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: accountSwitchMouse
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
if (root.manualUsernameEntry)
|
||||||
|
root.returnToUserListFromManualEntry();
|
||||||
|
else
|
||||||
|
root.enterManualUsernameEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 38
|
Layout.preferredHeight: 38
|
||||||
|
|||||||
@@ -8,10 +8,23 @@ Item {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool expanded: false
|
property bool expanded: false
|
||||||
|
property int maxExpandedHeight: 400
|
||||||
|
|
||||||
signal userSelected(string username)
|
signal userSelected(string username)
|
||||||
signal toggleRequested()
|
signal toggleRequested()
|
||||||
|
|
||||||
|
readonly property int rowHeight: 52
|
||||||
|
readonly property int collapsedBarHeight: 36
|
||||||
|
readonly property int expandedListHeight: {
|
||||||
|
if (!expanded)
|
||||||
|
return 0;
|
||||||
|
const count = GreeterUsersService.users.length;
|
||||||
|
if (count === 0)
|
||||||
|
return 0;
|
||||||
|
const fullHeight = count * rowHeight + Math.max(0, count - 1) * Theme.spacingXS;
|
||||||
|
return Math.min(maxExpandedHeight, fullHeight);
|
||||||
|
}
|
||||||
|
|
||||||
function encodeFileUrl(path) {
|
function encodeFileUrl(path) {
|
||||||
if (!path)
|
if (!path)
|
||||||
return "";
|
return "";
|
||||||
@@ -25,20 +38,16 @@ Item {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitHeight: column.implicitHeight
|
implicitHeight: expanded ? expandedListHeight : collapsedBarHeight
|
||||||
implicitWidth: parent ? parent.width : 320
|
implicitWidth: parent ? parent.width : 320
|
||||||
|
|
||||||
ColumnLayout {
|
RowLayout {
|
||||||
id: column
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
spacing: Theme.spacingS
|
anchors.verticalCenter: expanded ? undefined : parent.verticalCenter
|
||||||
|
height: collapsedBarHeight
|
||||||
RowLayout {
|
visible: !expanded && !!GreeterState.username
|
||||||
Layout.fillWidth: true
|
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
visible: !root.expanded && !!GreeterState.username
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -62,9 +71,10 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
anchors.left: parent.left
|
||||||
Layout.preferredHeight: 36
|
anchors.right: parent.right
|
||||||
visible: !root.expanded && !GreeterState.username
|
height: collapsedBarHeight
|
||||||
|
visible: !expanded && !GreeterState.username
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -80,21 +90,27 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
DankListView {
|
||||||
Layout.fillWidth: true
|
id: userListView
|
||||||
spacing: Theme.spacingXS
|
|
||||||
visible: root.expanded
|
|
||||||
|
|
||||||
Repeater {
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
height: expandedListHeight
|
||||||
|
visible: expanded
|
||||||
|
clip: true
|
||||||
|
interactive: contentHeight > height
|
||||||
|
spacing: Theme.spacingXS
|
||||||
model: GreeterUsersService.users
|
model: GreeterUsersService.users
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
id: userRow
|
id: userRow
|
||||||
|
|
||||||
required property var modelData
|
required property var modelData
|
||||||
|
required property int index
|
||||||
|
|
||||||
Layout.fillWidth: true
|
width: userListView.width
|
||||||
Layout.preferredHeight: 52
|
height: root.rowHeight
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: userRowMouse.containsMouse ? Theme.surfacePressed : "transparent"
|
color: userRowMouse.containsMouse ? Theme.surfacePressed : "transparent"
|
||||||
border.color: GreeterState.username === userRow.modelData.username ? Theme.primary : "transparent"
|
border.color: GreeterState.username === userRow.modelData.username ? Theme.primary : "transparent"
|
||||||
@@ -136,6 +152,4 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user