fix(Onboarding): Back button appears on loading screen

- don't clear the stack, we might need it to show errors during login
(while displaying splash screen)
- use the `backAvailableHint` instead on the splash screen itself to
hide the back button
- when a login error happens, unwind (or recreate) the stack to show the
LoginScreen page again, together with the error message
- add a simulation of these 2 scenarios to StoryBook, together with
showing the splash screen after a login

Fixes #17352
This commit is contained in:
Lukáš Tinkl 2025-02-20 16:24:58 +01:00
parent c5085b3097
commit f9bda5ced4
No known key found for this signature in database
3 changed files with 36 additions and 7 deletions

View File

@ -166,6 +166,12 @@ SplitView {
// password signals
signal accountLoginError(string error, bool wrongPassword)
// (test) error handler
onAccountLoginError: function (error, wrongPassword) {
ctrlLoginResult.result = "<font color='red'>⛔</font>"
onboarding.unwindToLoginScreen()
}
}
biometricsAvailable: ctrlBiometrics.checked
@ -179,7 +185,6 @@ SplitView {
logs.logEvent("onFinished", ["flow", "data"], arguments)
console.warn("!!! SIMULATION: SHOWING SPLASH")
stack.clear()
stack.push(splashScreen, { runningProgressAnimation: true })
}
@ -188,7 +193,7 @@ SplitView {
// SIMULATION: emit an error in case of wrong password or PIN
if (method === Onboarding.LoginMethod.Password && data.password !== mockDriver.password) {
onboardingStore.accountLoginError("The impossible has happened", Math.random() < 0.5) // randomly fail between a wrong pass and some other error
onboardingStore.accountLoginError("", true)
ctrlLoginResult.result = "<font color='red'>⛔</font>"
} else if (method === Onboarding.LoginMethod.Keycard && data.pin !== mockDriver.pin) {
onboardingStore.keycardRemainingPinAttempts-- // SIMULATION: decrease the remaining PIN attempts
@ -200,6 +205,7 @@ SplitView {
ctrlLoginResult.result = "<font color='red'>⛔</font>"
} else {
ctrlLoginResult.result = "<font color='green'>✔</font>"
stack.push(splashScreen, { runningProgressAnimation: true })
}
}
@ -359,6 +365,7 @@ SplitView {
id: splashScreen
DidYouKnowSplashScreen {
readonly property bool backAvailableHint: false
property bool runningProgressAnimation
NumberAnimation on progress {
@ -460,6 +467,18 @@ SplitView {
visible: ctrlLoginScreen.checked
text: "Login result: %1".arg(result)
}
Button {
text: "Unwind"
visible: ctrlLoginScreen.checked && onboarding.stack.depth > 1 && !(onboarding.currentPage instanceof DidYouKnowSplashScreen)
onClicked: onboarding.unwindToLoginScreen()
}
Button {
text: "Simulate login error"
visible: ctrlLoginScreen.checked && onboarding.currentPage instanceof DidYouKnowSplashScreen
onClicked: onboarding.onboardingStore.accountLoginError("SIMULATION: Something bad happened", false)
}
}
RowLayout {

View File

@ -24,7 +24,7 @@ Page {
property bool networkChecksEnabled: true
property alias keycardPinInfoPageDelay: onboardingFlow.keycardPinInfoPageDelay
readonly property alias stack: onboardingFlow
readonly property alias stack: onboardingFlow // TODO remove external stack access
readonly property string currentPageName: stack.topLevelItem ? Utils.objectTypeName(stack.topLevelItem) : ""
signal shareUsageDataRequested(bool enabled)
@ -49,6 +49,16 @@ Page {
d.resetState()
}
// clear the stack down to the LoginScreen, or recreate it
// the purpose is to return from main/splash screen in case of a late stage error
// and use the below error handler (onAccountLoginError)
function unwindToLoginScreen() {
onboardingFlow.pop(null, StackView.PopTransition)
if (!onboardingFlow.loginScreen) {
restartFlow()
}
}
function setBiometricResponse(secret: string, error = "",
detailedError = "",
wrongFingerprint = false) {
@ -216,10 +226,10 @@ Page {
}
}
// error handler for the LoginScreen
Connections {
target: root.onboardingStore
// (password) login
function onAccountLoginError(error: string, wrongPassword: bool) {
const loginScreen = onboardingFlow.loginScreen

View File

@ -198,7 +198,7 @@ StatusWindow {
Theme.changeTheme(localAppSettings.theme, systemPalette.isCurrentSystemThemeDark())
Theme.changeFontSize(localAccountSensitiveSettings.fontSize)
d.runMockedKeycardControllerWindow() // FIXME this is run twice with onboardingV1
d.runMockedKeycardControllerWindow()
}
//TODO remove direct backend access
@ -395,6 +395,7 @@ StatusWindow {
Component {
id: splashScreenV2
DidYouKnowSplashScreen {
readonly property bool backAvailableHint: false
readonly property string pageClassName: "Splash"
property bool runningProgressAnimation
messagesEnabled: true
@ -475,7 +476,6 @@ StatusWindow {
console.error("!!! ONBOARDING FINISHED WITH ERROR:", error)
return
}
stack.clear()
stack.push(splashScreenV2, { runningProgressAnimation: true })
}
@ -500,7 +500,7 @@ StatusWindow {
moveToAppMain()
}
onAccountLoginError: function (error, wrongPassword) {
onboardingLayout.stack.pop()
onboardingLayout.unwindToLoginScreen() // error handled internally
}
}