status-im / status-desktop

Status Desktop client made in Nim & QML
https://status.app
Mozilla Public License 2.0
304 stars 79 forks source link

[Onboarding UI] Create new Onboarding NIM backend #16832

Open caybro opened 6 days ago

caybro commented 6 days ago

Description

For the new onboarding redesign/rework (https://github.com/status-im/status-desktop/issues/16712), there is a need for a new matching backend.

Currently, the QML UI uses a mocked backend, modeled after existing StartupStore and PrivacyStore:

startupStore: StartupStore {
    readonly property var currentStartupState: QtObject {
        property string stateType: keycardMock.stateType  // Constants.startupState.keycardXXX
    }
    function getPasswordStrengthScore(password) {
        logs.logEvent("StartupStore.getPasswordStrengthScore", ["password"], arguments)
        return Math.min(password.length-1, 4)
    }
    function validMnemonic(mnemonic) {
        logs.logEvent("StartupStore.validMnemonic", ["mnemonic"], arguments)
        return mnemonic === keycardMock.mnemonic
    }
    function getPin() {
        logs.logEvent("StartupStore.getPin()")
        return ctrlPin.text
    }
    function getSeedPhrase() {
        logs.logEvent("StartupStore.getSeedPhrase()")
        // FIXME needed? cf getMnemonic()
    }
    function validateLocalPairingConnectionString(connectionString) {
        logs.logEvent("StartupStore.validateLocalPairingConnectionString", ["connectionString"], arguments)
        return !Number.isNaN(parseInt(connectionString))
    }
    function setConnectionString(connectionString) {
        logs.logEvent("StartupStore.setConnectionString", ["connectionString"], arguments)
    }
    readonly property var startupModuleInst: QtObject {
        property int remainingAttempts: 5
    }
}

privacyStore: PrivacyStore {
    readonly property var words: ["apple", "banana", "cat", "cow", "catalog", "catch", "category", "cattle", "dog", "elephant", "fish", "grape"]
    function getMnemonic() {
        logs.logEvent("PrivacyStore.getMnemonic()")
        return words.join(" ")
    }
    function mnemonicWasShown() {
        console.warn("!!! MNEMONIC SHOWN")
        logs.logEvent("PrivacyStore.mnemonicWasShown()")
    }
    function removeMnemonic() {
        console.warn("!!! REMOVE MNEMONIC")
        logs.logEvent("PrivacyStore.removeMnemonic()")
    }
}

QtObject {
    id: keycardMock
    property string stateType: ctrlKeycardState.currentValue
    readonly property var keycardStates: [
        // initial
        Constants.startupState.keycardNoPCSCService,
        Constants.startupState.keycardPluginReader,
        Constants.startupState.keycardInsertKeycard,
        Constants.startupState.keycardInsertedKeycard,
        Constants.startupState.keycardReadingKeycard,
        Constants.startupState.keycardRecognizedKeycard,
        // initial errors
        Constants.startupState.keycardWrongKeycard,
        Constants.startupState.keycardNotKeycard,
        Constants.startupState.keycardMaxPairingSlotsReached,
        Constants.startupState.keycardLocked,
        // exit states
        Constants.startupState.keycardNotEmpty,
        Constants.startupState.keycardEmpty
    ]
    readonly property string mnemonic: "dog dog dog dog dog dog dog dog dog dog dog dog"
}

This gives us an idea of the functions that need to be implemented. Ideally, these would live in a new store (e.g. OnboardingStore) which would encapsulate the new backend.

Acceptance Criteria

caybro commented 6 days ago

CC @iurimatias @jrainville @igor-sirotin

jrainville commented 6 days ago

@caybro would the new backend need to handle the navigation like the old one or it's all handled by the front-end now?

caybro commented 6 days ago

@caybro would the new backend need to handle the navigation like the old one or it's all handled by the front-end now?

Completely handled by the frontend stack now (navigation, sequence, transitions from page to page, etc).

My further thoughts: I could start sketching the proposed new OnboardingStore. This would continue to be the engine for Storybook now and at the same time this would give us the "contract" upon which we can actually implement the new backend

jrainville commented 6 days ago

@igor-sirotin and I checked this issue real quick and realized that there are missing functions in the mock, like login, createAccount, etc.

Is this because the UI changes are still WIP? @caybro

caybro commented 6 days ago

@igor-sirotin and I checked this issue real quick and realized that there are missing functions in the mock, like login, createAccount, etc.

Is this because the UI changes are still WIP? @caybro

"Login" in the sense of logging in with an already created account is not handled here in the onboarding (cf "Login" in these onboarding flows rather refers to "restoring an account"). See the "Log in with an existing profile" section in the Figma here: https://www.figma.com/design/Lw4nPYQcZOPOwTgETiiIYo/Desktop-Onboarding-Redesign?node-id=788-34574&node-type=instance&m=dev That would be for another epic/issue I guess

For actually processing the data collected throughout the onboarding flows, I'm not calling any backend action. When any of the onboarding flows is finished, it merely emits this signal:

signal finished(int primaryPath, int secondaryPath, var data)

where data contains the info collected, e.g.:

data: {"password":"0123456789","keycardPin":"","enableBiometrics":true,"syncConnectionString":""}

for a "Create Profile" -> "Password" flow