Refactor PromptModel to use semantic Reason objects instead of ra…#1652
Refactor PromptModel to use semantic Reason objects instead of ra…#1652TheBlackBit wants to merge 1 commit intoopenwallet-foundation:mainfrom
PromptModel to use semantic Reason objects instead of ra…#1652Conversation
There was a problem hiding this comment.
Pull request overview
Refactors the prompt system to use semantic Reason objects (converted via PromptModel.toHumanReadable) instead of passing user-visible title/subtitle directly, aiming to unify prompt copy and ensure flows consistently use the app-configured PromptModel.
Changes:
- Updated passphrase + biometric prompt APIs and dialog models to carry
Reasoninstead of raw UI strings. - Threaded
toHumanReadableconversion into Compose/Web/iOS UIs and Swift wrappers so UI derives copy fromReason. - Updated test app configurations and several Android presentment entry points to use
TestAppConfiguration.promptModel.
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| samples/testapp/src/wasmJsMain/kotlin/org/multipaz/testapp/TestAppConfiguration.wasmJs.kt | Adds app-specific toHumanReadable mapping and wires it into WebPromptModel.Builder. |
| samples/testapp/src/iosMain/kotlin/org/multipaz/testapp/TestAppConfiguration.ios.kt | Adds app-specific toHumanReadable mapping and wires it into IosPromptModel.Builder. |
| samples/testapp/src/commonMain/kotlin/org/multipaz/testapp/TestAppConfiguration.kt | Introduces expected appToHumanReadable(...) for platform-specific reason→copy conversion. |
| samples/testapp/src/androidMain/kotlin/org/multipaz/testapp/ui/ConsentPromptScreen.android.kt | Switches presentment coroutine context and biometric prompt calls to use app prompt model + Reason. |
| samples/testapp/src/androidMain/kotlin/org/multipaz/testapp/TestAppUriSchemePresentmentActivity.kt | Overrides base activity prompt model to reuse the app-configured Android prompt model. |
| samples/testapp/src/androidMain/kotlin/org/multipaz/testapp/TestAppMdocNdefService.kt | Passes app-configured prompt model into NFC presentment settings. |
| samples/testapp/src/androidMain/kotlin/org/multipaz/testapp/TestAppCredentialManagerPresentmentActivity.kt | Overrides base activity prompt model to reuse the app-configured Android prompt model. |
| samples/testapp/src/androidMain/kotlin/org/multipaz/testapp/TestAppConfiguration.android.kt | Adds app-specific toHumanReadable mapping and wires it into AndroidPromptModel.Builder. |
| samples/SwiftTestApp/SwiftTestApp/PassphrasePromptScreen.swift | Migrates Swift sample usage to pass ReasonHumanReadable instead of title/subtitle. |
| multipaz/src/commonTest/kotlin/org/multipaz/prompt/PromptModelTest.kt | Updates tests to use Reason.HumanReadable and asserts through the new parameters shape. |
| multipaz/src/commonMain/kotlin/org/multipaz/securearea/software/SoftwareSecureArea.kt | Switches passphrase prompting to pass Reason through instead of precomputed title/subtitle. |
| multipaz/src/commonMain/kotlin/org/multipaz/securearea/cloud/CloudSecureArea.kt | Switches passphrase prompting to pass Reason through instead of precomputed title/subtitle. |
| multipaz/src/commonMain/kotlin/org/multipaz/prompt/PromptModelExt.kt | Updates requestPassphrase extension signature to take Reason. |
| multipaz/src/commonMain/kotlin/org/multipaz/prompt/PassphrasePromptDialogModel.kt | Changes PassphraseRequest to carry Reason instead of title/subtitle. |
| multipaz/src/androidMain/kotlin/org/multipaz/securearea/AndroidKeystoreDefaultKeyUnlockDataProvider.kt | Updates biometric prompting to pass Reason instead of title/subtitle. |
| multipaz/src/androidMain/kotlin/org/multipaz/prompt/BiometricPromptDialogModel.kt | Changes biometric prompt dialog state to carry Reason. |
| multipaz/src/androidMain/kotlin/org/multipaz/prompt/AndroidPromptModelExt.kt | Updates showBiometricPrompt extension signature to take Reason. |
| multipaz-swift/Sources/MultipazSwift/PromptModelExt.swift | Updates Swift wrapper requestPassphrase to accept Reason and adds a Kotlin→Swift toHumanReadable bridge. |
| multipaz-swift/Sources/MultipazSwift/PromptDialogs.swift | Wires SwiftUI prompt dialogs to derive title/subtitle via the prompt model’s toHumanReadable. |
| multipaz-swift/Sources/MultipazSwift/PassphrasePromptDialog.swift | Updates SwiftUI passphrase dialog to render title/subtitle from a computed human-readable reason. |
| multipaz-compose/src/webMain/kotlin/org/multipaz/compose/prompt/PromptDialogs.web.kt | Passes a toHumanReadable lambda into the web passphrase dialog. |
| multipaz-compose/src/iosMain/kotlin/org/multipaz/compose/prompt/PromptDialogs.ios.kt | Passes a toHumanReadable lambda into the iOS passphrase dialog. |
| multipaz-compose/src/commonMain/kotlin/org/multipaz/compose/prompt/PassphrasePromptDialog.kt | Converts Reason→human-readable in the Compose passphrase dialog before rendering. |
| multipaz-compose/src/androidMain/kotlin/org/multipaz/compose/prompt/PromptDialogs.android.kt | Wires Android Compose dialogs to call toHumanReadable for biometric + passphrase prompts. |
| multipaz-compose/src/androidMain/kotlin/org/multipaz/compose/prompt/BiometricPromptDialog.kt | Converts Reason→human-readable before showing the platform biometric prompt. |
| multipaz-compose/src/androidMain/kotlin/org/multipaz/compose/presentment/UriSchemePresentmentActivity.kt | Makes the activity prompt model overridable so apps can supply their configured instance. |
| multipaz-compose/src/androidMain/kotlin/org/multipaz/compose/digitalcredentials/CredentialManagerPresentmentActivity.kt | Makes the activity prompt model overridable so apps can supply their configured instance. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
multipaz-compose/src/commonMain/kotlin/org/multipaz/compose/prompt/PassphrasePromptDialog.kt
Show resolved
Hide resolved
multipaz-swift/Sources/MultipazSwift/PassphrasePromptDialog.swift
Outdated
Show resolved
Hide resolved
samples/testapp/src/androidMain/kotlin/org/multipaz/testapp/TestAppConfiguration.android.kt
Outdated
Show resolved
Hide resolved
samples/testapp/src/iosMain/kotlin/org/multipaz/testapp/TestAppConfiguration.ios.kt
Outdated
Show resolved
Hide resolved
samples/testapp/src/androidMain/kotlin/org/multipaz/testapp/ui/ConsentPromptScreen.android.kt
Outdated
Show resolved
Hide resolved
samples/testapp/src/androidMain/kotlin/org/multipaz/testapp/TestAppMdocNdefService.kt
Outdated
Show resolved
Hide resolved
3f27cfe to
d488bc2
Compare
| abstract suspend fun getSettings(): Settings | ||
|
|
||
| private val promptModel = AndroidPromptModel.Builder().apply { addCommonDialogs() }.build() | ||
| protected open val promptModel = AndroidPromptModel.Builder().apply { addCommonDialogs() }.build() |
There was a problem hiding this comment.
Instead of having the app inject toHumanReadable() into the PromptModel - necessitating opening this up so an app can do this - wouldn't it be a lot easier if we just did it by changing PromptDialogs() to take a new parameter like this
@Composable
expect fun PromptDialogs(
promptModel: PromptModel,
imageLoader: ImageLoader? = null,
maxHeight: Dp? = null,
excludeTypes: List<PromptDialogModel.DialogType<*>> = emptyList(),
toHumanReadable: suspend (unlockReason: Reason, passphraseConstraints: PassphraseConstraints?) = defaultToHumanReadable
)
where defaultToHumanReadable() is part of multipaz-compose and using translated strings. Same for the one in Swift. That way you wouldn't have to change TestApp at all, I think!
There was a problem hiding this comment.
(Btw, TestAppConfiguration.promptModel should probably be removed, it's confusing we still have it. It predates Platform.promptModel being a thing, which should be used instead. I just tried removing it locally and it worked fine. If you want to include deletion of this in your next upload I think it would help.)
There was a problem hiding this comment.
Will, do it thank you 👌🏽
d488bc2 to
f09ed49
Compare
…w strings. This change migrates `BiometricPromptState` and `PassphraseRequest` to use a `Reason` object, allowing the UI layer to resolve human-readable titles and subtitles via `PromptModel.toHumanReadable`. This decoupling enables better localization and application-specific customization of security prompts. Key changes: - Updated `requestPassphrase` and `showBiometricPrompt` to accept a `Reason` parameter. - Modified Compose and Swift UI components to asynchronously resolve `Reason` into `HumanReadable` text before display. - Updated `AndroidKeystoreDefaultKeyUnlockDataProvider`, `CloudSecureArea`, and `SoftwareSecureArea` to pass semantic reasons instead of pre-formatted strings. - Implemented `appToHumanReadable` in the Test App across Android, iOS, and Web platforms to handle custom string mapping. - Adjusted `PromptModelTest` and `SwiftTestApp` to reflect the new API structure. - Exposed `promptModel` in `CredentialManagerPresentmentActivity` and `UriSchemePresentmentActivity` to allow subclasses to provide custom implementations. Signed-off-by: Ever Morales <ever.morales@koombea.com>
f09ed49 to
f41640e
Compare
Fixes #1651
Summary
Unified prompt flows to consistently use the app-configured PromptModel instead of fallback/default model instances.
Standardized prompt copy derivation to Reason -> toHumanReadable so title/subtitle are consistent across entry points and platforms.
Updated related docs/KDocs to reflect the current contract prompt UI text comes from human-readable reason conversion, not direct request fields.