status-desktop/ui/app/AppLayouts/Onboarding2/OnboardingLayout.qml
Lukáš Tinkl 7547442e39 fix(OnboardingFlow): collect enableBiometrics and seedphrase data
- extend the  tests to verify whether we collected the correct data
- restore the "pointing hand" cursor on clickable elements
- some minor improvements
2025-01-14 10:49:42 +01:00

184 lines
5.2 KiB
QML

import QtQuick 2.15
import QtQuick.Controls 2.15
import Qt.labs.settings 1.1
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
import AppLayouts.Onboarding2.pages 1.0
import AppLayouts.Onboarding2.stores 1.0
import AppLayouts.Onboarding.enums 1.0
import shared.stores 1.0 as SharedStores
import utils 1.0
Page {
id: root
required property OnboardingStore onboardingStore
// TODO backend: externalize the metrics handling too?
required property SharedStores.MetricsStore metricsStore
property int splashScreenDurationMs: 30000
property bool biometricsAvailable: Qt.platform.os === Constants.mac
property bool networkChecksEnabled
readonly property alias stack: stack
// flow: Onboarding.SecondaryFlow
signal finished(int flow, var data)
signal keycardFactoryResetRequested() // TODO integrate/switch to an external flow, needed?
signal keycardReloaded()
function restartFlow() {
stack.clear()
d.resetState()
d.settings.reset()
onboardingFlow.init()
}
QtObject {
id: d
// constants
readonly property int numWordsToVerify: 4
// state collected
property string password
property string keycardPin
property bool enableBiometrics
property string seedphrase
function resetState() {
d.password = ""
d.keycardPin = ""
d.enableBiometrics = false
d.seedphrase = ""
}
readonly property Settings settings: Settings {
property bool keycardPromoShown // whether we've seen the keycard promo banner on KeycardIntroPage
function reset() {
keycardPromoShown = false
}
}
function finishFlow(flow) {
const data = {
password: d.password,
keycardPin: d.keycardPin,
seedphrase: d.seedphrase,
enableBiometrics: d.enableBiometrics
}
root.finished(flow, data)
}
}
// page stack
OnboardingStackView {
id: stack
objectName: "stack"
anchors.fill: parent
readonly property bool backAvailable:
stack.currentItem ? (stack.currentItem.backAvailableHint ?? true)
: false
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.BackButton
enabled: stack.depth > 1 && !stack.busy
cursorShape: undefined
onClicked: stack.pop()
}
StatusBackButton {
width: 44
height: 44
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.margins: Theme.padding
opacity: stack.depth > 1 && !stack.busy && stack.backAvailable ? 1 : 0
visible: opacity > 0
Behavior on opacity {
NumberAnimation { duration: 100 }
}
onClicked: stack.pop()
}
OnboardingFlow {
id: onboardingFlow
stackView: stack
keycardState: root.onboardingStore.keycardState
syncState: root.onboardingStore.syncState
addKeyPairState: root.onboardingStore.addKeyPairState
seedWords: root.onboardingStore.getMnemonic().split(" ")
displayKeycardPromoBanner: !d.settings.keycardPromoShown
biometricsAvailable: root.biometricsAvailable
splashScreenDurationMs: root.splashScreenDurationMs
networkChecksEnabled: root.networkChecksEnabled
passwordStrengthScoreFunction: root.onboardingStore.getPasswordStrengthScore
isSeedPhraseValid: root.onboardingStore.validMnemonic
validateConnectionString: root.onboardingStore.validateLocalPairingConnectionString
tryToSetPinFunction: root.onboardingStore.setPin
remainingAttempts: root.onboardingStore.keycardRemainingPinAttempts
onKeycardPinCreated: (pin) => {
d.keycardPin = pin
root.onboardingStore.setPin(pin)
}
onKeycardPinEntered: (pin) => {
d.keycardPin = pin
root.onboardingStore.setPin(pin)
}
onShareUsageDataRequested: (enabled) => {
root.metricsStore.toggleCentralizedMetrics(enabled)
Global.addCentralizedMetricIfEnabled(
"usage_data_shared",
{ placement: Constants.metricsEnablePlacement.onboarding })
localAppSettings.metricsPopupSeen = true
}
onSyncProceedWithConnectionString: (connectionString) =>
root.onboardingStore.inputConnectionStringForBootstrapping(connectionString)
onSeedphraseSubmitted: (seedphrase) => d.seedphrase = seedphrase
onSetPasswordRequested: (password) => d.password = password
onEnableBiometricsRequested: (enabled) => d.enableBiometrics = enabled
onFinished: (flow) => d.finishFlow(flow)
}
Connections {
target: stack.currentItem
ignoreUnknownSignals: true
function onOpenLink(link: string) {
Global.openLink(link)
}
function onOpenLinkWithConfirmation(link: string, domain: string) {
Global.openLinkWithConfirmation(link, domain)
}
}
Component.onCompleted: root.restartFlow()
}