Skip to content

Commit

Permalink
Merge pull request #10 from niscy-eudiw/main
Browse files Browse the repository at this point in the history
Adds logic to show a Badge if the Verifier is trusted, in the Request Screen.
  • Loading branch information
stzouvaras authored Feb 6, 2024
2 parents 54abd1d + e823eb5 commit 8ca948a
Show file tree
Hide file tree
Showing 14 changed files with 211 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ sealed class TransferEventPartialState {
data class QrEngagementReady(val qrCode: String) : TransferEventPartialState()
data class RequestReceived(
val requestData: List<RequestDocument>,
val verifierName: String?
) :
TransferEventPartialState()
val verifierName: String?,
val verifierIsTrusted: Boolean,
) : TransferEventPartialState()

data object ResponseSent : TransferEventPartialState()
data class Redirect(val uri: URI) : TransferEventPartialState()
Expand Down Expand Up @@ -211,10 +211,13 @@ class WalletCorePresentationControllerImpl(
onRequestReceived = { requestDocuments ->
verifierName =
requestDocuments.firstOrNull()?.docRequest?.readerAuth?.readerCommonName
val verifierIsTrusted =
requestDocuments.firstOrNull()?.docRequest?.readerAuth?.readerSignIsValid == true
trySendBlocking(
TransferEventPartialState.RequestReceived(
requestData = requestDocuments,
verifierName = verifierName
verifierName = verifierName,
verifierIsTrusted = verifierIsTrusted
)
)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import eu.europa.ec.uilogic.component.AppIcons
import eu.europa.ec.uilogic.component.content.ContentScreen
import eu.europa.ec.uilogic.component.content.ContentTitle
import eu.europa.ec.uilogic.component.content.ScreenNavigateAction
import eu.europa.ec.uilogic.component.content.TitleWithBadge
import eu.europa.ec.uilogic.component.preview.PreviewTheme
import eu.europa.ec.uilogic.component.preview.ThemeModePreviews
import eu.europa.ec.uilogic.component.utils.OneTimeLaunchedEffect
Expand Down Expand Up @@ -153,7 +154,12 @@ private fun Content(
) {
// Screen Title.
ContentTitle(
title = state.screenTitle,
titleWithBadge = state.screenTitle,
onTitleWithBadgeClick = if (state.screenTitle.isTrusted) {
{ onEventSend(Event.BadgeClicked) }
} else {
null
},
subtitle = state.screenSubtitle,
clickableSubtitle = state.screenClickableSubtitle,
onSubtitleClick = { onEventSend(Event.SubtitleClicked) },
Expand Down Expand Up @@ -218,6 +224,15 @@ private fun SheetContent(
onEventSent: (event: Event) -> Unit
) {
when (sheetContent) {
RequestBottomSheetContent.BADGE -> {
DialogBottomSheet(
title = stringResource(id = R.string.request_bottom_sheet_badge_title),
message = stringResource(id = R.string.request_bottom_sheet_badge_subtitle),
positiveButtonText = stringResource(id = R.string.request_bottom_sheet_badge_primary_button_text),
onPositiveClick = { onEventSent(Event.BottomSheet.Badge.PrimaryButtonPressed) },
)
}

RequestBottomSheetContent.SUBTITLE -> {
DialogBottomSheet(
title = stringResource(id = R.string.request_bottom_sheet_subtitle_title),
Expand Down Expand Up @@ -285,7 +300,7 @@ private fun ContentPreview() {
PreviewTheme {
Content(
state = State(
screenTitle = "Title",
screenTitle = TitleWithBadge(isTrusted = false),
screenSubtitle = "Subtitle ",
screenClickableSubtitle = "clickable subtitle",
warningText = "Warning",
Expand Down Expand Up @@ -328,7 +343,7 @@ private fun StickyBottomSectionPreview() {
PreviewTheme {
StickyBottomSection(
state = State(
screenTitle = "Title",
screenTitle = TitleWithBadge(isTrusted = false),
screenSubtitle = "Subtitle ",
screenClickableSubtitle = "clickable subtitle",
warningText = "Warning",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package eu.europa.ec.commonfeature.ui.request
import eu.europa.ec.businesslogic.di.getOrCreatePresentationScope
import eu.europa.ec.commonfeature.ui.request.model.RequestDataUi
import eu.europa.ec.uilogic.component.content.ContentErrorConfig
import eu.europa.ec.uilogic.component.content.TitleWithBadge
import eu.europa.ec.uilogic.config.NavigationType
import eu.europa.ec.uilogic.mvi.MviViewModel
import eu.europa.ec.uilogic.mvi.ViewEvent
Expand All @@ -34,7 +35,7 @@ data class State(
val sheetContent: RequestBottomSheetContent = RequestBottomSheetContent.SUBTITLE,

val verifierName: String? = null,
val screenTitle: String,
val screenTitle: TitleWithBadge,
val screenSubtitle: String,
val screenClickableSubtitle: String?,
val warningText: String,
Expand All @@ -51,6 +52,7 @@ sealed class Event : ViewEvent {
data class ExpandOrCollapseRequiredDataList(val id: Int) : Event()
data class UserIdentificationClicked(val itemId: String) : Event()

data object BadgeClicked : Event()
data object SubtitleClicked : Event()
data object PrimaryButtonPressed : Event()
data object SecondaryButtonPressed : Event()
Expand All @@ -66,6 +68,10 @@ sealed class Event : ViewEvent {
sealed class Subtitle : BottomSheet() {
data object PrimaryButtonPressed : Subtitle()
}

sealed class Badge : BottomSheet() {
data object PrimaryButtonPressed : Subtitle()
}
}
}

Expand All @@ -86,7 +92,7 @@ sealed class Effect : ViewSideEffect {
}

enum class RequestBottomSheetContent {
SUBTITLE, CANCEL
BADGE, SUBTITLE, CANCEL
}

abstract class RequestViewModel : MviViewModel<Event, State, Effect>() {
Expand Down Expand Up @@ -117,7 +123,7 @@ abstract class RequestViewModel : MviViewModel<Event, State, Effect>() {

override fun setInitialState(): State {
return State(
screenTitle = "",
screenTitle = TitleWithBadge(isTrusted = false),
screenSubtitle = getScreenSubtitle(),
screenClickableSubtitle = getScreenClickableSubtitle(),
warningText = getWarningText(),
Expand Down Expand Up @@ -157,6 +163,10 @@ abstract class RequestViewModel : MviViewModel<Event, State, Effect>() {
updateUserIdentificationItem(id = event.itemId)
}

is Event.BadgeClicked -> {
showBottomSheet(sheetContent = RequestBottomSheetContent.BADGE)
}

is Event.SubtitleClicked -> {
showBottomSheet(sheetContent = RequestBottomSheetContent.SUBTITLE)
}
Expand Down Expand Up @@ -187,6 +197,10 @@ abstract class RequestViewModel : MviViewModel<Event, State, Effect>() {
is Event.BottomSheet.Subtitle.PrimaryButtonPressed -> {
hideBottomSheet()
}

is Event.BottomSheet.Badge.PrimaryButtonPressed -> {
hideBottomSheet()
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,14 @@ import kotlinx.coroutines.flow.mapNotNull
sealed class PresentationRequestInteractorPartialState {
data class Success(
val verifierName: String? = null,
val verifierIsTrusted: Boolean,
val requestDocuments: List<RequestDataUi<Event>>
) : PresentationRequestInteractorPartialState()

data class NoData(val verifierName: String? = null) :
PresentationRequestInteractorPartialState()
data class NoData(
val verifierName: String? = null,
val verifierIsTrusted: Boolean,
) : PresentationRequestInteractorPartialState()

data class Failure(val error: String) : PresentationRequestInteractorPartialState()
data object Disconnect : PresentationRequestInteractorPartialState()
Expand Down Expand Up @@ -69,7 +72,8 @@ class PresentationRequestInteractorImpl(
is TransferEventPartialState.RequestReceived -> {
if (response.requestData.all { it.docRequest.requestItems.isEmpty() }) {
PresentationRequestInteractorPartialState.NoData(
verifierName = response.verifierName
verifierName = response.verifierName,
verifierIsTrusted = response.verifierIsTrusted,
)
} else {
val requestDataUi = RequestTransformer.transformToUiItems(
Expand All @@ -80,6 +84,7 @@ class PresentationRequestInteractorImpl(
)
PresentationRequestInteractorPartialState.Success(
verifierName = response.verifierName,
verifierIsTrusted = response.verifierIsTrusted,
requestDocuments = requestDataUi
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,11 @@ class PresentationLoadingViewModel(

override fun getTitle(): String {
return if (interactor.verifierName.isNullOrBlank()) {
resourceProvider.getString(R.string.request_title)
resourceProvider.getString(R.string.request_title_before_badge) +
resourceProvider.getString(R.string.request_title_after_badge)
} else {
resourceProvider.getString(
R.string.request_title_with_verifier_name,
interactor.verifierName
?: resourceProvider.getString(R.string.presentation_loading_success_config_verifier)
)
interactor.verifierName +
resourceProvider.getString(R.string.request_title_after_badge)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import eu.europa.ec.presentationfeature.interactor.PresentationRequestInteractor
import eu.europa.ec.resourceslogic.R
import eu.europa.ec.resourceslogic.provider.ResourceProvider
import eu.europa.ec.uilogic.component.content.ContentErrorConfig
import eu.europa.ec.uilogic.component.content.TitleWithBadge
import eu.europa.ec.uilogic.config.ConfigNavigation
import eu.europa.ec.uilogic.config.NavigationType
import eu.europa.ec.uilogic.navigation.CommonScreens
Expand Down Expand Up @@ -65,7 +66,7 @@ class PresentationRequestViewModel(
mapOf(
BiometricUiConfig.serializedKeyName to uiSerializer.toBase64(
BiometricUiConfig(
title = viewState.value.screenTitle,
title = viewState.value.screenTitle.plainText,
subTitle = resourceProvider.getString(R.string.loading_biometry_share_subtitle),
quickPinOnlySubTitle = resourceProvider.getString(R.string.loading_quick_pin_share_subtitle),
isPreAuthorization = false,
Expand Down Expand Up @@ -123,7 +124,10 @@ class PresentationRequestViewModel(
isLoading = false,
error = null,
verifierName = response.verifierName,
screenTitle = getScreenTitle(verifierName),
screenTitle = getScreenTitle(
verifierName = response.verifierName,
verifierIsTrusted = response.verifierIsTrusted
),
items = response.requestDocuments
)
}
Expand All @@ -139,7 +143,10 @@ class PresentationRequestViewModel(
isLoading = false,
error = null,
verifierName = response.verifierName,
screenTitle = getScreenTitle(verifierName),
screenTitle = getScreenTitle(
verifierName = response.verifierName,
verifierIsTrusted = response.verifierIsTrusted
),
noItems = true,
)
}
Expand All @@ -159,11 +166,19 @@ class PresentationRequestViewModel(
interactor.stopPresentation()
}

private fun getScreenTitle(verifierName: String?): String {
return if (verifierName.isNullOrBlank()) {
resourceProvider.getString(R.string.request_title)
private fun getScreenTitle(verifierName: String?, verifierIsTrusted: Boolean): TitleWithBadge {
val textBeforeBadge = if (verifierName.isNullOrBlank()) {
resourceProvider.getString(R.string.request_title_before_badge)
} else {
resourceProvider.getString(R.string.request_title_with_verifier_name, verifierName)
verifierName
}

val textAfterBadge = resourceProvider.getString(R.string.request_title_after_badge)

return TitleWithBadge(
textBeforeBadge = textBeforeBadge,
textAfterBadge = textAfterBadge,
isTrusted = verifierIsTrusted
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,14 @@ import kotlinx.coroutines.flow.mapNotNull
sealed class ProximityRequestInteractorPartialState {
data class Success(
val verifierName: String? = null,
val verifierIsTrusted: Boolean,
val requestDocuments: List<RequestDataUi<Event>>
) : ProximityRequestInteractorPartialState()

data class NoData(val verifierName: String? = null) : ProximityRequestInteractorPartialState()
data class NoData(
val verifierName: String? = null,
val verifierIsTrusted: Boolean,
) : ProximityRequestInteractorPartialState()

data class Failure(val error: String) : ProximityRequestInteractorPartialState()
data object Disconnect : ProximityRequestInteractorPartialState()
Expand Down Expand Up @@ -68,7 +72,8 @@ class ProximityRequestInteractorImpl(
is TransferEventPartialState.RequestReceived -> {
if (response.requestData.all { it.docRequest.requestItems.isEmpty() }) {
ProximityRequestInteractorPartialState.NoData(
verifierName = response.verifierName
verifierName = response.verifierName,
verifierIsTrusted = response.verifierIsTrusted,
)
} else {
val requestDataUi = RequestTransformer.transformToUiItems(
Expand All @@ -79,6 +84,7 @@ class ProximityRequestInteractorImpl(
)
ProximityRequestInteractorPartialState.Success(
verifierName = response.verifierName,
verifierIsTrusted = response.verifierIsTrusted,
requestDocuments = requestDataUi
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,11 @@ class ProximityLoadingViewModel(

override fun getTitle(): String {
return if (interactor.verifierName.isNullOrBlank()) {
resourceProvider.getString(R.string.request_title)
resourceProvider.getString(R.string.request_title_before_badge) +
resourceProvider.getString(R.string.request_title_after_badge)
} else {
resourceProvider.getString(
R.string.request_title_with_verifier_name,
interactor.verifierName
?: resourceProvider.getString(R.string.presentation_loading_success_config_verifier)
)
interactor.verifierName +
resourceProvider.getString(R.string.request_title_after_badge)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class ProximityQRViewModel(

is Event.GoBack -> {
cleanUp()
setState { copy(error = null) }
setEffect { Effect.Navigation.Pop }
}

Expand Down
Loading

0 comments on commit 8ca948a

Please sign in to comment.