fix(@desktop/keycard): onboarding flow `I already use Status` -> `Login with Keycard` updated

Onboarding flow updated according to the latest related
figma changes.
This commit is contained in:
Sale Djenic 2022-09-29 15:30:17 +02:00 committed by saledjenic
parent eb5ad8c911
commit 095578b517
31 changed files with 262 additions and 249 deletions

View File

@ -19,6 +19,7 @@ type PredefinedKeycardData* {.pure.} = enum
OfferPukForUnlock = 16
UseUnlockLabelForLockedState = 32
UseGeneralMessageForLockedState = 64
MaxPUKReached = 128
# Forward declaration
proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: State): State

View File

@ -209,6 +209,12 @@ proc getSeedPhraseLength*(self: Controller): int =
proc setKeyUid*(self: Controller, value: string) =
self.tmpKeyUid = value
proc getKeyUid*(self: Controller): string =
self.tmpKeyUid
proc getKeycardData*(self: Controller): string =
return self.delegate.getKeycardData()
proc setKeycardData*(self: Controller, value: string) =
self.delegate.setKeycardData(value)
@ -267,7 +273,7 @@ proc validMnemonic*(self: Controller, mnemonic: string): bool =
return true
return false
proc importMnemonic*(self: Controller): bool =
proc importMnemonic(self: Controller): bool =
let error = self.accountsService.importMnemonic(self.tmpSeedPhrase)
if(error.len == 0):
self.delegate.importAccountSuccess()
@ -369,6 +375,10 @@ proc loginAccountKeycard*(self: Controller) =
if(error.len > 0):
self.delegate.emitAccountLoginError(error)
proc getKeyUidForSeedPhrase*(self: Controller, seedPhrase: string): string =
let acc = self.accountsService.createAccountFromMnemonic(seedPhrase)
return acc.keyUid
proc seedPhraseRefersToSelectedKeyPair*(self: Controller, seedPhrase: string): bool =
let selectedAccount = self.getSelectedLoginAccount()
let accFromSP = self.accountsService.createAccountFromMnemonic(seedPhrase)

View File

@ -14,7 +14,8 @@ method executeBackCommand*(self: KeycardCreatePinState, controller: Controller)
controller.setPin("")
controller.setPinMatch(false)
if self.flowType == FlowType.FirstRunNewUserNewKeycardKeys or
self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard:
self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard or
self.flowType == FlowType.FirstRunOldUserKeycardImport:
controller.cancelCurrentFlow()
method getNextPrimaryState*(self: KeycardCreatePinState, controller: Controller): State =

View File

@ -10,7 +10,8 @@ proc delete*(self: KeycardInsertKeycardState) =
method executeBackCommand*(self: KeycardInsertKeycardState, controller: Controller) =
if self.flowType == FlowType.FirstRunNewUserNewKeycardKeys or
self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard:
self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard or
self.flowType == FlowType.FirstRunOldUserKeycardImport:
controller.cancelCurrentFlow()
method resolveKeycardNextState*(self: KeycardInsertKeycardState, keycardFlowType: string, keycardEvent: KeycardEvent,
@ -21,9 +22,9 @@ method resolveKeycardNextState*(self: KeycardInsertKeycardState, keycardFlowType
if keycardFlowType == ResponseTypeValueInsertCard and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorConnection:
controller.setKeycardData(ResponseTypeValueInsertCard)
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WronglyInsertedCard, add = true))
return nil
if keycardFlowType == ResponseTypeValueCardInserted:
controller.setKeycardData("")
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WronglyInsertedCard, add = false))
return createState(StateType.KeycardInsertedKeycard, self.flowType, self.getBackState)
return nil

View File

@ -10,7 +10,8 @@ proc delete*(self: KeycardInsertedKeycardState) =
method executeBackCommand*(self: KeycardInsertedKeycardState, controller: Controller) =
if self.flowType == FlowType.FirstRunNewUserNewKeycardKeys or
self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard:
self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard or
self.flowType == FlowType.FirstRunOldUserKeycardImport:
controller.cancelCurrentFlow()
method getNextPrimaryState*(self: KeycardInsertedKeycardState, controller: Controller): State =

View File

@ -1,9 +1,13 @@
type
KeycardNotKeycardState* = ref object of State
KeycardLockedState* = ref object of State
proc newKeycardNotKeycardState*(flowType: FlowType, backState: State): KeycardNotKeycardState =
result = KeycardNotKeycardState()
result.setup(flowType, StateType.KeycardNotKeycard, backState)
proc newKeycardLockedState*(flowType: FlowType, backState: State): KeycardLockedState =
result = KeycardLockedState()
result.setup(flowType, StateType.KeycardLocked, backState)
proc delete*(self: KeycardNotKeycardState) =
self.State.delete
proc delete*(self: KeycardLockedState) =
self.State.delete
method executePrimaryCommand*(self: KeycardLockedState, controller: Controller) =
if self.flowType == FlowType.FirstRunNewUserNewKeycardKeys:
controller.runFactoryResetPopup()

View File

@ -8,14 +8,6 @@ proc newKeycardMaxPairingSlotsReachedState*(flowType: FlowType, backState: State
proc delete*(self: KeycardMaxPairingSlotsReachedState) =
self.State.delete
method executePrimaryCommand*(self: KeycardMaxPairingSlotsReachedState, controller: Controller) =
method getNextPrimaryState*(self: KeycardMaxPairingSlotsReachedState, controller: Controller): State =
if self.flowType == FlowType.FirstRunOldUserKeycardImport:
controller.runFactoryResetPopup()
method executeSecondaryCommand*(self: KeycardMaxPairingSlotsReachedState, controller: Controller) =
if self.flowType == FlowType.FirstRunOldUserKeycardImport:
controller.runRecoverAccountFlow()
method resolveKeycardNextState*(self: KeycardMaxPairingSlotsReachedState, keycardFlowType: string, keycardEvent: KeycardEvent,
controller: Controller): State =
return ensureReaderAndCardPresenceAndResolveNextOnboardingState(self, keycardFlowType, keycardEvent, controller)
return createState(StateType.KeycardRecover, self.flowType(), self)

View File

@ -9,4 +9,5 @@ proc delete*(self: KeycardMaxPinRetriesReachedState) =
self.State.delete
method getNextPrimaryState*(self: KeycardMaxPinRetriesReachedState, controller: Controller): State =
return createState(StateType.KeycardRecover, self.flowType(), self.getBackState)
if self.flowType == FlowType.FirstRunOldUserKeycardImport:
return createState(StateType.KeycardRecover, self.flowType(), self)

View File

@ -8,14 +8,6 @@ proc newKeycardMaxPukRetriesReachedState*(flowType: FlowType, backState: State):
proc delete*(self: KeycardMaxPukRetriesReachedState) =
self.State.delete
method executePrimaryCommand*(self: KeycardMaxPukRetriesReachedState, controller: Controller) =
method getNextPrimaryState*(self: KeycardMaxPukRetriesReachedState, controller: Controller): State =
if self.flowType == FlowType.FirstRunOldUserKeycardImport:
controller.runFactoryResetPopup()
method executeSecondaryCommand*(self: KeycardMaxPukRetriesReachedState, controller: Controller) =
if self.flowType == FlowType.FirstRunOldUserKeycardImport:
controller.runRecoverAccountFlow()
method resolveKeycardNextState*(self: KeycardMaxPukRetriesReachedState, keycardFlowType: string, keycardEvent: KeycardEvent,
controller: Controller): State =
return ensureReaderAndCardPresenceAndResolveNextOnboardingState(self, keycardFlowType, keycardEvent, controller)
return createState(StateType.KeycardRecover, self.flowType(), self)

View File

@ -1,13 +1,9 @@
type
KeycardLockedState* = ref object of State
KeycardNotKeycardState* = ref object of State
proc newKeycardLockedState*(flowType: FlowType, backState: State): KeycardLockedState =
result = KeycardLockedState()
result.setup(flowType, StateType.KeycardLocked, backState)
proc newKeycardNotKeycardState*(flowType: FlowType, backState: State): KeycardNotKeycardState =
result = KeycardNotKeycardState()
result.setup(flowType, StateType.KeycardNotKeycard, backState)
proc delete*(self: KeycardLockedState) =
self.State.delete
method executePrimaryCommand*(self: KeycardLockedState, controller: Controller) =
if self.flowType == FlowType.FirstRunNewUserNewKeycardKeys:
controller.runFactoryResetPopup()
proc delete*(self: KeycardNotKeycardState) =
self.State.delete

View File

@ -10,7 +10,8 @@ proc delete*(self: KeycardPluginReaderState) =
method executeBackCommand*(self: KeycardPluginReaderState, controller: Controller) =
if self.flowType == FlowType.FirstRunNewUserNewKeycardKeys or
self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard:
self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard or
self.flowType == FlowType.FirstRunOldUserKeycardImport:
controller.cancelCurrentFlow()
method resolveKeycardNextState*(self: KeycardPluginReaderState, keycardFlowType: string, keycardEvent: KeycardEvent,

View File

@ -10,7 +10,8 @@ proc delete*(self: KeycardReadingKeycardState) =
method executeBackCommand*(self: KeycardReadingKeycardState, controller: Controller) =
if self.flowType == FlowType.FirstRunNewUserNewKeycardKeys or
self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard:
self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard or
self.flowType == FlowType.FirstRunOldUserKeycardImport:
controller.cancelCurrentFlow()
method getNextPrimaryState*(self: KeycardReadingKeycardState, controller: Controller): State =

View File

@ -10,7 +10,8 @@ proc delete*(self: KeycardRecognizedKeycardState) =
method executeBackCommand*(self: KeycardRecognizedKeycardState, controller: Controller) =
if self.flowType == FlowType.FirstRunNewUserNewKeycardKeys or
self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard:
self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard or
self.flowType == FlowType.FirstRunOldUserKeycardImport:
controller.cancelCurrentFlow()
method getNextPrimaryState*(self: KeycardRecognizedKeycardState, controller: Controller): State =
@ -18,3 +19,5 @@ method getNextPrimaryState*(self: KeycardRecognizedKeycardState, controller: Con
return createState(StateType.KeycardCreatePin, self.flowType, self.getBackState)
if self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard:
return createState(StateType.UserProfileEnterSeedPhrase, self.flowType, self.getBackState)
if self.flowType == FlowType.FirstRunOldUserKeycardImport:
return createState(StateType.KeycardEnterPin, self.flowType, self.getBackState)

View File

@ -0,0 +1,9 @@
type
KeycardWrongKeycardState* = ref object of State
proc newKeycardWrongKeycardState*(flowType: FlowType, backState: State): KeycardWrongKeycardState =
result = KeycardWrongKeycardState()
result.setup(flowType, StateType.KeycardWrongKeycard, backState)
proc delete*(self: KeycardWrongKeycardState) =
self.State.delete

View File

@ -33,6 +33,7 @@ method resolveKeycardNextState*(self: KeycardWrongPukState, keycardFlowType: str
if keycardFlowType == ResponseTypeValueSwapCard and
keycardEvent.error.len > 0 and
keycardEvent.error == RequestParamPUKRetries:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.MaxPUKReached, add = true))
return createState(StateType.KeycardMaxPukRetriesReached, self.flowType, self.getBackState)
if keycardFlowType == ResponseTypeValueKeycardFlowResult:
controller.setKeycardEvent(keycardEvent)

View File

@ -35,9 +35,9 @@ method resolveKeycardNextState*(self: LoginKeycardInsertKeycardState, keycardFlo
if keycardFlowType == ResponseTypeValueInsertCard and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorConnection:
controller.setKeycardData(ResponseTypeValueInsertCard)
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WronglyInsertedCard, add = true))
return nil
if keycardFlowType == ResponseTypeValueCardInserted:
controller.setKeycardData("")
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WronglyInsertedCard, add = false))
return createState(StateType.LoginKeycardReadingKeycard, self.flowType, nil)
return nil

View File

@ -32,6 +32,7 @@ type StateType* {.pure.} = enum
KeycardInsertedKeycard = "KeycardInsertedKeycard"
KeycardReadingKeycard = "KeycardReadingKeycard"
KeycardRecognizedKeycard = "KeycardRecognizedKeycard"
KeycardWrongKeycard = "KeycardWrongKeycard"
KeycardCreatePin = "KeycardCreatePin"
KeycardRepeatPin = "KeycardRepeatPin"
KeycardPinSet = "KeycardPinSet"

View File

@ -6,6 +6,9 @@ from ../../../../app_service/service/keycard/service import PINLengthForStatusAp
from ../../../../app_service/service/keycard/service import PUKLengthForStatusApp
import state
from ../../shared_modules/keycard_popup/internal/state_factory import PredefinedKeycardData
from ../../shared_modules/keycard_popup/internal/state_factory import updatePredefinedKeycardData
logScope:
topics = "startup-module-state-factory"
@ -37,6 +40,7 @@ include keycard_reading_keycard_state
include keycard_recognized_keycard_state
include keycard_recover_state
include keycard_repeat_pin_state
include keycard_wrong_keycard_state
include keycard_wrong_pin_state
include keycard_wrong_puk_state
include notification_state
@ -106,6 +110,8 @@ proc createState*(stateToBeCreated: StateType, flowType: FlowType, backState: St
return newKeycardWrongPinState(flowType, backState)
if stateToBeCreated == StateType.KeycardEnterPuk:
return newKeycardEnterPukState(flowType, backState)
if stateToBeCreated == StateType.KeycardWrongKeycard:
return newKeycardWrongKeycardState(flowType, backState)
if stateToBeCreated == StateType.KeycardWrongPuk:
return newKeycardWrongPukState(flowType, backState)
if stateToBeCreated == StateType.KeycardDisplaySeedPhrase:
@ -168,7 +174,7 @@ proc ensureReaderAndCardPresenceOnboarding*(state: State, keycardFlowType: strin
return nil
return createState(StateType.KeycardInsertKeycard, state.flowType, state.getBackState)
if keycardFlowType == ResponseTypeValueCardInserted:
controller.setKeycardData("")
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WronglyInsertedCard, add = false))
return createState(StateType.KeycardInsertedKeycard, state.flowType, state.getBackState)
proc ensureReaderAndCardPresenceLogin*(state: State, keycardFlowType: string, keycardEvent: KeycardEvent, controller: Controller): State =
@ -186,7 +192,7 @@ proc ensureReaderAndCardPresenceLogin*(state: State, keycardFlowType: string, ke
return nil
return createState(StateType.LoginKeycardInsertKeycard, state.flowType, state.getBackState)
if keycardFlowType == ResponseTypeValueCardInserted:
controller.setKeycardData("")
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.WronglyInsertedCard, add = false))
return createState(StateType.LoginKeycardReadingKeycard, state.flowType, state.getBackState)
proc ensureReaderAndCardPresenceAndResolveNextOnboardingState*(state: State, keycardFlowType: string, keycardEvent: KeycardEvent, controller: Controller): State =
@ -252,9 +258,11 @@ proc ensureReaderAndCardPresenceAndResolveNextOnboardingState*(state: State, key
return createState(StateType.KeycardPinSet, state.flowType, state.getBackState)
if state.flowType == FlowType.FirstRunOldUserKeycardImport:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.MaxPUKReached, add = false))
controller.setKeyUid(keycardEvent.keyUid)
if keycardFlowType == ResponseTypeValueEnterPIN and
keycardEvent.error.len == 0:
return createState(StateType.KeycardEnterPin, state.flowType, state.getBackState)
return createState(StateType.KeycardRecognizedKeycard, state.flowType, state.getBackState)
if keycardFlowType == ResponseTypeValueEnterPUK and
keycardEvent.error.len == 0:
if keycardEvent.pinRetries == 0 and keycardEvent.pukRetries > 0:
@ -262,10 +270,11 @@ proc ensureReaderAndCardPresenceAndResolveNextOnboardingState*(state: State, key
if keycardFlowType == ResponseTypeValueSwapCard and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorNoKeys:
return createState(StateType.KeycardEmpty, state.flowType, state.getBackState)
return createState(StateType.KeycardEmpty, state.flowType, nil)
if keycardFlowType == ResponseTypeValueSwapCard and
keycardEvent.error.len > 0 and
keycardEvent.error == RequestParamPUKRetries:
controller.setKeycardData(updatePredefinedKeycardData(controller.getKeycardData(), PredefinedKeycardData.MaxPUKReached, add = true))
return createState(StateType.KeycardMaxPukRetriesReached, state.flowType, state.getBackState)
if keycardFlowType == ResponseTypeValueSwapCard and
keycardEvent.error.len > 0 and
@ -274,7 +283,7 @@ proc ensureReaderAndCardPresenceAndResolveNextOnboardingState*(state: State, key
if keycardFlowType == ResponseTypeValueEnterNewPIN and
keycardEvent.error.len > 0 and
keycardEvent.error == ErrorRequireInit:
return createState(StateType.KeycardCreatePin, state.flowType, state.getBackState)
return createState(StateType.KeycardCreatePin, state.flowType, nil)
if state.flowType == FlowType.AppLogin:
if keycardFlowType == ResponseTypeValueSwapCard and

View File

@ -1,11 +1,13 @@
type
UserProfileEnterSeedPhraseState* = ref object of State
successfulImport: bool
correctKeycard: bool
proc newUserProfileEnterSeedPhraseState*(flowType: FlowType, backState: State): UserProfileEnterSeedPhraseState =
result = UserProfileEnterSeedPhraseState()
result.setup(flowType, StateType.UserProfileEnterSeedPhrase, backState)
result.successfulImport = false
result.correctKeycard = false
proc delete*(self: UserProfileEnterSeedPhraseState) =
self.State.delete
@ -20,6 +22,9 @@ method getNextPrimaryState*(self: UserProfileEnterSeedPhraseState, controller: C
if self.flowType == FlowType.FirstRunOldUserImportSeedPhrase or
self.flowType == FlowType.FirstRunNewUserImportSeedPhrase:
return createState(StateType.UserProfileCreate, self.flowType, self)
if self.flowType == FlowType.FirstRunOldUserKeycardImport:
if not self.correctKeycard:
return createState(StateType.KeycardWrongKeycard, self.flowType, nil)
method executePrimaryCommand*(self: UserProfileEnterSeedPhraseState, controller: Controller) =
if self.flowType == FlowType.AppLogin:
@ -28,12 +33,14 @@ method executePrimaryCommand*(self: UserProfileEnterSeedPhraseState, controller:
if self.successfulImport:
controller.runLoadAccountFlow(controller.getSeedPhraseLength(), controller.getSeedPhrase(), puk = "", factoryReset = true)
else:
self.successfulImport = controller.importMnemonic()
self.successfulImport = controller.validMnemonic(controller.getSeedPhrase())
if self.successfulImport:
if self.flowType == FlowType.FirstRunNewUserImportSeedPhraseIntoKeycard:
controller.storeSeedPhraseToKeycard(controller.getSeedPhraseLength(), controller.getSeedPhrase())
elif self.flowType == FlowType.FirstRunOldUserKeycardImport:
controller.runLoadAccountFlow(controller.getSeedPhraseLength(), controller.getSeedPhrase(), puk = "", factoryReset = true)
if self.flowType == FlowType.FirstRunOldUserKeycardImport:
self.correctKeycard = controller.getKeyUidForSeedPhrase(controller.getSeedPhrase()) == controller.getKeyUid()
if self.correctKeycard:
controller.runLoadAccountFlow(controller.getSeedPhraseLength(), controller.getSeedPhrase(), puk = "", factoryReset = true)
method resolveKeycardNextState*(self: UserProfileEnterSeedPhraseState, keycardFlowType: string, keycardEvent: KeycardEvent,
controller: Controller): State =

View File

@ -118,6 +118,9 @@ method checkRepeatedKeycardPinWhileTyping*(self: AccessInterface, pin: string):
method getSeedPhrase*(self: AccessInterface): string {.base.} =
raise newException(ValueError, "No implementation available")
method getKeycardData*(self: AccessInterface): string {.base.} =
raise newException(ValueError, "No implementation available")
method setKeycardData*(self: AccessInterface, value: string) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -295,6 +295,9 @@ method checkRepeatedKeycardPinWhileTyping*[T](self: Module[T], pin: string): boo
method getSeedPhrase*[T](self: Module[T]): string =
return self.controller.getSeedPhrase()
method getKeycardData*[T](self: Module[T]): string =
return self.view.getKeycardData()
method setKeycardData*[T](self: Module[T], value: string) =
self.view.setKeycardData(value)

View File

@ -184,9 +184,7 @@ QtObject:
self.startFlow(payload)
proc startRecoverAccountFlow*(self: Service, seedPhraseLength: int, seedPhrase: string, puk: string, factoryReset: bool) =
var payload = %* {
RequestParamOverwrite: true
}
var payload = %* { }
if seedPhrase.len > 0 and seedPhraseLength > 0:
payload[RequestParamMnemonic] = %* seedPhrase
payload[RequestParamMnemonicLen] = %* seedPhraseLength

View File

@ -104,6 +104,7 @@ OnboardingBasePage {
if (root.startupStore.currentStartupState.stateType === Constants.startupState.keycardNotEmpty ||
root.startupStore.currentStartupState.stateType === Constants.startupState.keycardNotKeycard ||
root.startupStore.currentStartupState.stateType === Constants.startupState.keycardEmpty ||
root.startupStore.currentStartupState.stateType === Constants.startupState.keycardWrongKeycard ||
root.startupStore.currentStartupState.stateType === Constants.startupState.keycardLocked ||
root.startupStore.currentStartupState.stateType === Constants.startupState.keycardRecover ||
root.startupStore.currentStartupState.stateType === Constants.startupState.keycardMaxPairingSlotsReached ||

View File

@ -29,7 +29,7 @@ Item {
ColumnLayout {
anchors.centerIn: parent
height: Constants.keycard.general.onboardingHeight
spacing: Style.current.padding
spacing: Style.current.bigPadding
KeycardImage {
id: image
@ -123,7 +123,7 @@ Item {
}
PropertyChanges {
target: info
visible: root.startupStore.startupModuleInst.keycardData !== ""
visible: root.startupStore.startupModuleInst.keycardData & Constants.predefinedKeycardData.wronglyInsertedCard
text: qsTr("Check the card, it might be wrongly inserted")
font.pixelSize: Constants.keycard.general.fontSize3
color: Theme.palette.baseColor1

View File

@ -48,7 +48,7 @@ Item {
ColumnLayout {
anchors.centerIn: parent
height: Constants.keycard.general.onboardingHeight
spacing: Style.current.padding
spacing: Style.current.bigPadding
KeycardImage {
id: image

View File

@ -49,120 +49,114 @@ Item {
}
}
Item {
anchors.top: parent.top
anchors.bottom: footerWrapper.top
anchors.left: parent.left
anchors.right: parent.right
ColumnLayout {
anchors.centerIn: parent
height: Constants.keycard.general.onboardingHeight
spacing: Style.current.bigPadding
ColumnLayout {
anchors.centerIn: parent
spacing: Style.current.padding
StatusBaseText {
id: title
Layout.alignment: Qt.AlignHCenter
font.pixelSize: Constants.keycard.general.fontSize1
font.weight: Font.Bold
color: Theme.palette.directColor1
text: qsTr("Enter PUK code to recover Keycard")
}
StatusBaseText {
id: title
Layout.alignment: Qt.AlignHCenter
font.pixelSize: Constants.keycard.general.fontSize1
font.weight: Font.Bold
color: Theme.palette.directColor1
text: qsTr("Enter PUK code to recover Keycard")
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
}
RowLayout {
id: rowLayout
Layout.alignment: Qt.AlignHCenter
spacing: d.rowSpacing
RowLayout {
id: rowLayout
Layout.alignment: Qt.AlignHCenter
spacing: d.rowSpacing
Component.onCompleted: {
for (var i = 0; i < children.length - 1; ++i) {
if(children[i] && children[i].input && children[i+1] && children[i+1].input){
children[i].input.tabNavItem = children[i+1].input.edit
}
}
if(children.length > 0){
children[0].input.edit.forceActiveFocus()
Component.onCompleted: {
for (var i = 0; i < children.length - 1; ++i) {
if(children[i] && children[i].input && children[i+1] && children[i+1].input){
children[i].input.tabNavItem = children[i+1].input.edit
}
}
if(children.length > 0){
children[0].input.edit.forceActiveFocus()
}
}
Repeater {
model: d.pukLength
delegate: StatusInput {
Layout.preferredWidth: Constants.keycard.general.pukCellWidth
Layout.preferredHeight: Constants.keycard.general.pukCellHeight
input.acceptReturn: true
validators: [
StatusRegularExpressionValidator {
regularExpression: /[0-9]/
errorMessage: ""
},
StatusMinLengthValidator {
minLength: 1
errorMessage: ""
}
]
onTextChanged: {
text = text.trim()
if(text.length >= 1) {
text = text.charAt(0);
}
if(Utils.isDigit(text)) {
let nextInd = index+1
if(nextInd <= rowLayout.children.length - 1 &&
rowLayout.children[nextInd] &&
rowLayout.children[nextInd].input){
rowLayout.children[nextInd].input.edit.forceActiveFocus()
}
}
else {
text = ""
}
d.pukArray[index] = text
d.updateValidity()
Repeater {
model: d.pukLength
delegate: StatusInput {
Layout.preferredWidth: Constants.keycard.general.pukCellWidth
Layout.preferredHeight: Constants.keycard.general.pukCellHeight
input.acceptReturn: true
validators: [
StatusRegularExpressionValidator {
regularExpression: /[0-9]/
errorMessage: ""
},
StatusMinLengthValidator {
minLength: 1
errorMessage: ""
}
]
onKeyPressed: {
if(input.edit.keyEvent === Qt.Key_Backspace){
if (text == ""){
let prevInd = index-1
if(prevInd >= 0){
rowLayout.children[prevInd].input.edit.forceActiveFocus()
}
onTextChanged: {
text = text.trim()
if(text.length >= 1) {
text = text.charAt(0);
}
if(Utils.isDigit(text)) {
let nextInd = index+1
if(nextInd <= rowLayout.children.length - 1 &&
rowLayout.children[nextInd] &&
rowLayout.children[nextInd].input){
rowLayout.children[nextInd].input.edit.forceActiveFocus()
}
}
else {
text = ""
}
d.pukArray[index] = text
d.updateValidity()
}
onKeyPressed: {
if(input.edit.keyEvent === Qt.Key_Backspace){
if (text == ""){
let prevInd = index-1
if(prevInd >= 0){
rowLayout.children[prevInd].input.edit.forceActiveFocus()
}
}
else if (input.edit.keyEvent === Qt.Key_Return ||
input.edit.keyEvent === Qt.Key_Enter) {
if(d.allEntriesValid) {
event.accepted = true
d.submitPuk()
}
}
else if (input.edit.keyEvent === Qt.Key_Return ||
input.edit.keyEvent === Qt.Key_Enter) {
if(d.allEntriesValid) {
event.accepted = true
d.submitPuk()
}
}
}
}
}
StatusBaseText {
id: info
Layout.alignment: Qt.AlignHCenter
font.pixelSize: Constants.keycard.general.fontSize3
color: Theme.palette.dangerColor1
horizontalAlignment: Qt.AlignHCenter
}
}
}
Item {
id: footerWrapper
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
height: Constants.keycard.general.footerWrapperHeight
StatusBaseText {
id: info
Layout.alignment: Qt.AlignHCenter
font.pixelSize: Constants.keycard.general.fontSize3
color: Theme.palette.dangerColor1
horizontalAlignment: Qt.AlignHCenter
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
}
StatusButton {
anchors.top: parent.top
anchors.topMargin: Style.current.padding
anchors.horizontalCenter: parent.horizontalCenter
Layout.alignment: Qt.AlignHCenter
enabled: d.allEntriesValid
text: qsTr("Recover Keycard")
onClicked: {

View File

@ -20,7 +20,7 @@ Item {
ColumnLayout {
anchors.centerIn: parent
height: Constants.keycard.general.onboardingHeight
spacing: Style.current.padding
spacing: Style.current.bigPadding
KeycardImage {
id: image
@ -37,7 +37,9 @@ Item {
StatusBaseText {
id: info
visible: text.length > 0
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
}
@ -74,6 +76,7 @@ Item {
StatusBaseText {
id: message
visible: text.length > 0
Layout.alignment: Qt.AlignHCenter
wrapMode: Text.WordWrap
}
@ -131,12 +134,14 @@ Item {
}
PropertyChanges {
target: title
text: ""
text: qsTr("Keycard is empty")
color: Theme.palette.directColor1
font.pixelSize: Constants.keycard.general.fontSize1
}
PropertyChanges {
target: info
text: qsTr("The keycard is empty")
color: Theme.palette.dangerColor1
text: qsTr("There is no key pair on this Keycard")
color: Theme.palette.directColor1
font.pixelSize: Constants.keycard.general.fontSize2
}
PropertyChanges {
@ -232,8 +237,11 @@ Item {
}
},
State {
name: Constants.startupState.keycardMaxPairingSlotsReached
when: root.startupStore.currentStartupState.stateType === Constants.startupState.keycardMaxPairingSlotsReached
name: "lockedState"
when: root.startupStore.currentStartupState.stateType === Constants.startupState.keycardMaxPinRetriesReached ||
root.startupStore.currentStartupState.stateType === Constants.startupState.keycardMaxPukRetriesReached ||
root.startupStore.currentStartupState.stateType === Constants.startupState.keycardMaxPairingSlotsReached
PropertyChanges {
target: image
pattern: "keycard/strong_error/img-%1"
@ -252,92 +260,24 @@ Item {
}
PropertyChanges {
target: info
text: qsTr("Max pairing slots reached for this keycard")
text: {
let t = qsTr("You will need to unlock it before proceeding")
if (root.startupStore.currentStartupState.stateType === Constants.startupState.keycardMaxPinRetriesReached)
t += qsTr("\nMax PIN retries reached for this keycard")
if (root.startupStore.currentStartupState.stateType === Constants.startupState.keycardMaxPukRetriesReached)
t += qsTr("\nMax PUK retries reached for this keycard")
if (root.startupStore.currentStartupState.stateType === Constants.startupState.keycardMaxPairingSlotsReached)
t += qsTr("\nMax pairing slots reached for this keycard")
return t
}
color: Theme.palette.dangerColor1
font.pixelSize: Constants.keycard.general.fontSize2
}
PropertyChanges {
target: button
text: qsTr("Factory reset")
text: qsTr("Unlock Keycard")
type: StatusBaseButton.Type.Normal
}
PropertyChanges {
target: link
text: qsTr("Insert another Keycard")
color: Theme.palette.primaryColor1
}
PropertyChanges {
target: message
text: ""
}
},
State {
name: Constants.startupState.keycardMaxPukRetriesReached
when: root.startupStore.currentStartupState.stateType === Constants.startupState.keycardMaxPukRetriesReached
PropertyChanges {
target: image
pattern: "keycard/strong_error/img-%1"
source: ""
startImgIndexForTheFirstLoop: 0
startImgIndexForOtherLoops: 18
endImgIndex: 29
duration: 1300
loops: -1
}
PropertyChanges {
target: title
text: qsTr("Keycard locked")
color: Theme.palette.dangerColor1
font.pixelSize: Constants.keycard.general.fontSize1
}
PropertyChanges {
target: info
text: qsTr("Max PUK retries reached for this keycard")
color: Theme.palette.dangerColor1
font.pixelSize: Constants.keycard.general.fontSize2
}
PropertyChanges {
target: button
text: qsTr("Factory reset")
type: StatusBaseButton.Type.Normal
}
PropertyChanges {
target: link
text: qsTr("Insert another Keycard")
color: Theme.palette.primaryColor1
}
PropertyChanges {
target: message
text: ""
}
},
State {
name: Constants.startupState.keycardMaxPinRetriesReached
when: root.startupStore.currentStartupState.stateType === Constants.startupState.keycardMaxPinRetriesReached
PropertyChanges {
target: image
pattern: "keycard/strong_error/img-%1"
source: ""
startImgIndexForTheFirstLoop: 0
startImgIndexForOtherLoops: 18
endImgIndex: 29
duration: 1300
loops: -1
}
PropertyChanges {
target: title
text: ""
}
PropertyChanges {
target: info
text: qsTr("Keycard locked")
color: Theme.palette.dangerColor1
}
PropertyChanges {
target: button
text: qsTr("Recover your Keycard")
type: StatusBaseButton.Type.Danger
}
PropertyChanges {
target: link
text: ""
@ -362,7 +302,7 @@ Item {
}
PropertyChanges {
target: title
text: qsTr("Recover your Keycard")
text: qsTr("Unlock this Keycard")
color: Theme.palette.directColor1
font.pixelSize: Constants.keycard.general.fontSize1
}
@ -372,18 +312,59 @@ Item {
}
PropertyChanges {
target: button
text: qsTr("Recover with seed phrase")
type: StatusBaseButton.Type.Danger
text: qsTr("Unlock using seed phrase")
type: StatusBaseButton.Type.Normal
}
PropertyChanges {
target: link
text: qsTr("Recover with PUK")
color: Theme.palette.dangerColor1
text: qsTr("Unlock using PUK")
enabled: !(root.startupStore.startupModuleInst.keycardData & Constants.predefinedKeycardData.maxPUKReached)
color: !enabled? Theme.palette.baseColor1 : Theme.palette.primaryColor1
}
PropertyChanges {
target: message
text: ""
}
},
State {
name: Constants.startupState.keycardWrongKeycard
when: root.startupStore.currentStartupState.stateType === Constants.startupState.keycardWrongKeycard
PropertyChanges {
target: image
pattern: "keycard/strong_error/img-%1"
source: ""
startImgIndexForTheFirstLoop: 0
startImgIndexForOtherLoops: 18
endImgIndex: 29
duration: 1300
loops: -1
}
PropertyChanges {
target: title
text: qsTr("Wrong Keycard inserted")
color: Theme.palette.dangerColor1
font.pixelSize: Constants.keycard.general.fontSize1
}
PropertyChanges {
target: info
text: qsTr("The card inserted is not linked to your profile.")
color: Theme.palette.dangerColor1
font.pixelSize: Constants.keycard.general.fontSize2
}
PropertyChanges {
target: button
text: ""
}
PropertyChanges {
target: link
text: ""
}
PropertyChanges {
target: message
text: qsTr("Remove Keycard and try again")
color: Theme.palette.baseColor1
font.pixelSize: Constants.keycard.general.fontSize3
}
}
]
}

View File

@ -615,7 +615,7 @@ Item {
}
PropertyChanges {
target: message
visible: root.startupStore.startupModuleInst.keycardData !== ""
visible: root.startupStore.startupModuleInst.keycardData & Constants.predefinedKeycardData.wronglyInsertedCard
text: qsTr("Check the card, it might be wrongly inserted")
font.pixelSize: Constants.keycard.general.fontSize3
color: Theme.palette.baseColor1

View File

@ -42,7 +42,7 @@ Item {
ColumnLayout {
anchors.centerIn: parent
height: Constants.keycard.general.onboardingHeight
spacing: Style.current.padding
spacing: Style.current.bigPadding
StatusBaseText {
id: title

View File

@ -67,7 +67,7 @@ Item {
ColumnLayout {
anchors.centerIn: parent
height: Constants.keycard.general.onboardingHeight
spacing: Style.current.padding
spacing: Style.current.bigPadding
StatusBaseText {
id: title

View File

@ -42,6 +42,7 @@ QtObject {
readonly property string keycardInsertedKeycard: "KeycardInsertedKeycard"
readonly property string keycardReadingKeycard: "KeycardReadingKeycard"
readonly property string keycardRecognizedKeycard: "KeycardRecognizedKeycard"
readonly property string keycardWrongKeycard: "KeycardWrongKeycard"
readonly property string keycardCreatePin: "KeycardCreatePin"
readonly property string keycardRepeatPin: "KeycardRepeatPin"
readonly property string keycardPinSet: "KeycardPinSet"
@ -80,6 +81,7 @@ QtObject {
readonly property int offerPukForUnlock: 16
readonly property int useUnlockLabelForLockedState: 32
readonly property int useGeneralMessageForLockedState: 64
readonly property int maxPUKReached: 128
}
readonly property QtObject keycardSharedFlow: QtObject {