feat(keycard): noticeable delay in starting flows

This is not an issue actually, instead a request was if the Keycard is present to display an
appropriate state based on the Keycard content, which requires the following steps when a user
clicks any flow to run:
- run appropriate keycard flow
- wait for a response from the keycard
- resolving state that needs to be displayed based on the response
- display appropriate state

This commit changes that to the following:
- display keycard reading state immediately after the user clicks any flow to run and then the rest as it was
- run appropriate keycard flow
- wait for a response from the keycard
- resolving state that needs to be displayed based on the response
- display appropriate state

With this change on OS' where communication between the app and keycard is slow it wouldn't look
like a delay in running flow, but instead, a user will be aware immediately that something is ongoing.

Closes #13242
This commit is contained in:
Sale Djenic 2024-04-08 09:40:49 +02:00 committed by saledjenic
parent da7f419f57
commit ced5a9bb4b
1 changed files with 25 additions and 19 deletions

View File

@ -433,14 +433,14 @@ method onKeycardResponse*[T](self: Module[T], keycardFlowType: string, keycardEv
## Check local state first, in case postponed flow is run
if not self.tmpLocalState.isNil:
let nextState = self.tmpLocalState.resolveKeycardNextState(keycardFlowType, keycardEvent, self.controller)
defer: self.tmpLocalState.delete
defer: self.tmpLocalState = nil
defer:
self.tmpLocalState.delete
self.tmpLocalState = nil
if nextState.isNil:
return
self.preStateActivities(nextState.flowType(), nextState.stateType())
self.reEvaluateKeyPairForProcessing(self.tmpLocalState.flowType(), self.tmpLocalState.stateType())
self.view.setCurrentState(nextState)
self.controller.readyToDisplayPopup()
debug "sm_on_keycard_response - from_local - set state", setCurrFlow=nextState.flowType(), setCurrState=nextState.stateType()
return
## Check regular flows
@ -497,6 +497,12 @@ method prepareKeyPairForProcessing*[T](self: Module[T], keyUid: string, keycardU
item.setIcon("keycard")
self.view.setKeyPairForProcessing(item)
proc displayReadingState[T](self: Module[T], flowType: FlowType, backState: State) =
self.tmpLocalState = newReadingKeycardState(flowType, backState)
self.view.setCurrentState(self.tmpLocalState)
self.controller.readyToDisplayPopup()
debug "sm_cannot - display reading state", setCurrFlow=self.tmpLocalState.flowType(), setCurrState=self.tmpLocalState.stateType()
method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Paths: seq[string] = @[], txHash = "", forceFlow = false, returnToFlow = FlowType.General) =
## In case of `Authentication` or `Sign` flow, if keyUid is provided, that keypair will be authenticated,
## otherwise the logged in profile will be authenticated.
@ -519,7 +525,7 @@ proc proceedWithRunFlow[T](self: Module[T], flowToRun: FlowType, keyUid: string,
if flowToRun == FlowType.FactoryReset:
if keyUid.len > 0:
self.prepareKeyPairForProcessing(keyUid)
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runGetMetadataFlow(resolveAddress = true)
return
if flowToRun == FlowType.SetupNewKeycard:
@ -536,7 +542,7 @@ proc proceedWithRunFlow[T](self: Module[T], flowToRun: FlowType, keyUid: string,
self.controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false)
return
self.setSelectedKeyPair(filteredItems[0])
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runLoadAccountFlow()
return
if flowToRun == FlowType.Authentication:
@ -544,7 +550,7 @@ proc proceedWithRunFlow[T](self: Module[T], flowToRun: FlowType, keyUid: string,
if keyUid.len == 0 or keyUid == singletonInstance.userProfile.getKeyUid():
if singletonInstance.userProfile.getIsKeycardUser():
self.prepareKeyPairItemForAuthentication(singletonInstance.userProfile.getKeyUid())
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runAuthenticationFlow(singletonInstance.userProfile.getKeyUid(), bip44Paths)
if singletonInstance.userProfile.getUsingBiometricLogin():
self.controller.connectKeychainSignals()
@ -552,7 +558,7 @@ proc proceedWithRunFlow[T](self: Module[T], flowToRun: FlowType, keyUid: string,
return
self.view.setCurrentState(newEnterPasswordState(flowToRun, nil))
if singletonInstance.userProfile.getUsingBiometricLogin():
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.connectKeychainSignals()
self.controller.tryToObtainDataFromKeychain()
else:
@ -561,7 +567,7 @@ proc proceedWithRunFlow[T](self: Module[T], flowToRun: FlowType, keyUid: string,
return
else:
self.prepareKeyPairItemForAuthentication(keyUid)
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runAuthenticationFlow(keyUid, bip44Paths)
return
if flowToRun == FlowType.Sign:
@ -587,7 +593,7 @@ proc proceedWithRunFlow[T](self: Module[T], flowToRun: FlowType, keyUid: string,
return
self.runningFlow = flowToRun
self.prepareKeyPairItemForAuthentication(keyUid)
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runSignFlow(keyUid, bip44Paths[0], txHash)
if finalKeyUid == singletonInstance.userProfile.getKeyUid() and
singletonInstance.userProfile.getUsingBiometricLogin():
@ -598,48 +604,48 @@ proc proceedWithRunFlow[T](self: Module[T], flowToRun: FlowType, keyUid: string,
## since we can run unlock keycard flow from an already running flow, in order to avoid changing displayed keypair
## (locked keypair) we have to set keycard uid of a keycard used in the flow we're jumping from to `UnlockKeycard` flow.
self.prepareKeyPairForProcessing(keyUid, self.controller.getKeycardUid())
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runGetMetadataFlow(resolveAddress = true)
return
if flowToRun == FlowType.DisplayKeycardContent:
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runGetMetadataFlow(resolveAddress = true)
return
if flowToRun == FlowType.RenameKeycard:
self.prepareKeyPairForProcessing(keyUid)
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runGetMetadataFlow(resolveAddress = true) # we're firstly displaying the keycard content
return
if flowToRun == FlowType.ChangeKeycardPin:
self.prepareKeyPairForProcessing(keyUid)
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runChangePinFlow()
return
if flowToRun == FlowType.ChangeKeycardPuk:
self.prepareKeyPairForProcessing(keyUid)
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runChangePukFlow()
return
if flowToRun == FlowType.ChangePairingCode:
self.prepareKeyPairForProcessing(keyUid)
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runChangePairingFlow()
return
if flowToRun == FlowType.CreateCopyOfAKeycard:
self.prepareKeyPairForProcessing(keyUid)
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runGetMetadataFlow(resolveAddress = true)
return
if flowToRun == FlowType.SetupNewKeycardNewSeedPhrase:
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runLoadAccountFlow()
return
if flowToRun == FlowType.SetupNewKeycardOldSeedPhrase:
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runLoadAccountFlow()
return
if flowToRun == FlowType.ImportFromKeycard:
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
self.displayReadingState(flowToRun, nil)
self.controller.runGetMetadataFlow(resolveAddress = true, exportMasterAddr = true)
return
if flowToRun == FlowType.MigrateFromKeycardToApp: