Screen Providers Reference
Every screen in msa-core is a ComposableScreen<State, Action>: your Composable receives an immutable State
and a triggerAction callback.
fun interface ComposableScreen<S, A> {
@Composable
fun Content(state: S, triggerAction: (A) -> Unit)
}You create one from a lambda:
ComposableScreen<LoginState, LoginAction> { state, triggerAction -> MyLoginScreen(state, triggerAction) }How the screens are organised
ScreenProviders groups the screens by feature. Each group is an interface in
com.theminesec.multiplatform.msa_core.app.contract.screens, and msa-uikit provides an open default class for
each one:
interface ScreenProviders {
val statusBarColor: @Composable (AppScreen) -> Color
val themeWrapper: @Composable (content: @Composable () -> Unit) -> Unit
val startup: StartupScreens
val home: HomeScreens
val payment: PaymentScreens
val history: HistoryScreens
val settlement: SettlementScreens
val settings: SettingsScreens
val idle: IdleScreens
// App2App screens (see below)
}To replace one screen, subclass DefaultScreenProviders, then override the group with a subclass of its default
class, and override the one slot. Every other slot keeps tracking msa-uikit:
class MyScreenProviders : DefaultScreenProviders(MyBrandTheme) {
override val history: HistoryScreens = object : DefaultHistoryScreens() {
override val detail = ComposableScreen { state, triggerAction ->
MyTransactionDetail(state, triggerAction)
}
}
}Declare slots as stored properties (override val x = ...), never as getters. A getter creates a new screen on every
read and forces recomposition.
Replacing a screen changes only how it looks. msa-core validates every operation, whatever the UI offers.
Startup: startup
Default class: DefaultStartupScreens
| Slot | State | Action | Description |
|---|---|---|---|
login | LoginState | LoginAction | Passcode login, with optional biometrics |
landing | LandingState | LandingAction | Splash and activation screen |
Home: home
Default class: DefaultHomeScreens
| Slot | State | Action | Description |
|---|---|---|---|
home | HomeState | HomeAction | Main dashboard with navigation to all features |
Payment: payment
Default class: DefaultPaymentScreens. One payment, from the amount to the receipt.
| Slot | State | Action | Description |
|---|---|---|---|
amountEntry | AmountEntryState | AmountEntryAction | Amount entry for sale, pre-auth and refund. The operation is part of the state. |
methodSelection | PaymentSelectionState | PaymentSelectionAction | Payment method selection: card, merchant QR or consumer QR |
qrPresent | PaymentQRSelectionState | PaymentQRSelectionAction | The merchant's QR code, shown for the customer to scan |
qrScan | ConsumerQRScanState | ConsumerQRScanAction | The camera, scanning the customer's QR code |
cardPrompt | CardPromptState | CardPromptAction | Get ready, tap card and processing, in one screen. Rendered in the card-reading activity. |
processing | ProcessingInquiryState | ProcessingInquiryAction | Waiting for the acquirer's response |
receipt | ReceiptState | ReceiptAction | The full receipt |
The result of a payment is shown by history.detail: a transaction that just ran is the same record as one looked
up later.
History: history
Default class: DefaultHistoryScreens
| Slot | State | Action | Description |
|---|---|---|---|
list | HistoryState | HistoryAction | Transaction history list |
detail | TransactionDetailState | TransactionDetailAction | One transaction in full, including the result of a payment that just ran |
Settlement: settlement
Default class: DefaultSettlementScreens
| Slot | State | Action | Description |
|---|---|---|---|
list | SettlementState | SettlementAction | Batch settlement overview |
detail | SettlementState | SettlementAction | Settlement batch details |
Settings: settings
Default class: DefaultSettingsScreens
| Slot | State | Action | Description |
|---|---|---|---|
main | SettingsState | SettingsAction | Application settings |
info | SettingsState | SettingsAction | Merchant and terminal information |
Idle: idle
Default class: DefaultIdleScreens. What an unattended (kiosk) terminal shows when nobody is using it.
| Slot | State | Action | Description |
|---|---|---|---|
signage | KioskIdleSignageState | KioskIdleSignageAction | Idle signage in kiosk mode |
App-to-App Screens
These screens are shown when a POS app on the same device calls MineSec Pay 7 through
App2App. They are direct properties of ScreenProviders, not a
group.
| Property | State | Action | Description |
|---|---|---|---|
splashApp2AppScreen | SplashApp2AppState | SplashApp2AppAction | Loading screen while the request is read |
activationApp2AppScreen | ActivationApp2AppState | ActivationApp2AppAction | Activation requested by the POS app |
warmupApp2AppScreen | WarmupApp2AppState | WarmupApp2AppAction | Warm-up requested by the POS app |
saleApp2AppScreen | SaleApp2AppState | SaleApp2AppAction | Sale requested by the POS app |
voidRefundApp2AppScreen | VoidRefundApp2AppState | VoidRefundApp2AppAction | Void or refund requested by the POS app |
queryApp2AppScreen | QueryApp2AppState | QueryApp2AppAction | Transaction query requested by the POS app |
settlementApp2AppScreen | SettlementApp2AppState | SettlementApp2AppAction | Settlement requested by the POS app |
Override them directly in your DefaultScreenProviders subclass:
override val saleApp2AppScreen = ComposableScreen { state, triggerAction ->
MyApp2AppSaleScreen(state, triggerAction)
}Where the classes live
| Classes | Package |
|---|---|
ScreenProviders, ComposableScreen, ErrorState | com.theminesec.multiplatform.msa_core.app.contract |
Group interfaces (PaymentScreens, HistoryScreens, ...) | com.theminesec.multiplatform.msa_core.app.contract.screens |
AmountEntry*, CardPrompt*, TransactionDetail* | com.theminesec.multiplatform.msa_core.app.contract.models |
| Other State and Action classes | The feature's presentation package in msa-core, for example ...msa_core.feature.login.presentation.LoginState |
DefaultScreenProviders and the default group classes | com.theminesec.multiplatform.msa.screens and its sub-packages (msa-uikit) |
Your IDE's auto-import resolves them.
Status Bar Colour
statusBarColor picks the status bar colour for each screen. The stock implementation:
override val statusBarColor: @Composable (AppScreen) -> Color = { screen ->
when (screen) {
LandingScreen -> MsaTheme.colors.mutedForeground
LoginScreen -> MsaTheme.colors.background
HomeScreen -> MsaTheme.colors.surface
AmountEntryScreen -> MsaTheme.colors.primary
else -> MsaTheme.colors.background
}
}Override it in your DefaultScreenProviders subclass to change it.
Theme Wrapper
themeWrapper wraps the screens drawn outside the main activity: App2App and the card prompt. Override it with your
theme so that those screens are branded too. See
Applying your theme.