Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,20 @@ internal class ConsentFragment : Fragment(R.layout.fragment_consent) {

private fun updateUiWithState(state: ConsentViewState) {
binding.consentLogo.isVisible = state.showLogo

val generalText = state.consentTextBuilder?.assembleText(requireActivity()).orEmpty()
val parentText = state.parentalTextBuilder?.assembleText(requireActivity()).orEmpty()

// setup initial text to general consent
binding.consentTextHolderView.text = state.consentText
binding.consentTextHolderView.text = generalText

with(binding.consentTabHost) {
// Fully reset tab state
removeAllTabs()
clearOnTabSelectedListeners()
addTab(newTab().setText(IDR.string.consent_general_title), GENERAL_CONSENT_TAB)
if (state.showParentalConsent) {
addParentalConsentTab(state.consentText, state.parentalConsentText)
addParentalConsentTab(generalText, parentText)
}
getTabAt(state.selectedTab)?.select()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ internal class ConsentViewModel @Inject constructor(
private val timeHelper: TimeHelper,
private val configManager: ConfigManager,
private val eventRepository: SessionEventRepository,
private val generalConsentTextHelper: GeneralConsentTextHelper,
private val parentalConsentTextHelper: ParentalConsentTextHelper,
@ExternalScope private val externalScope: CoroutineScope,
) : ViewModel() {

Expand Down Expand Up @@ -95,27 +93,33 @@ internal class ConsentViewModel @Inject constructor(

return ConsentViewState(
showLogo = projectConfig.consent.displaySimprintsLogo,
consentText = generalConsentTextHelper
.assembleText(projectConfig.consent, projectConfig.general.modalities, consentType),
showParentalConsent = allowParentalConsent,
parentalConsentText = parentalConsentTextHelper
.takeIf { allowParentalConsent }
?.assembleText(projectConfig.consent, projectConfig.general.modalities, consentType)
.orEmpty(),
selectedTab = selectedTabIndex
consentTextBuilder = GeneralConsentTextHelper(
projectConfig.consent,
projectConfig.general.modalities,
consentType,
),
parentalTextBuilder = if (allowParentalConsent) ParentalConsentTextHelper(
projectConfig.consent,
projectConfig.general.modalities,
consentType,
) else null,
selectedTab = selectedTabIndex,
)
}

private fun saveConsentEvent(
currentConsentTab: ConsentTab,
result: ConsentEvent.ConsentPayload.Result
) = externalScope.launch {
eventRepository.addOrUpdateEvent(ConsentEvent(
startConsentEventTime,
timeHelper.now(),
currentConsentTab.asEventPayload(),
result
))
eventRepository.addOrUpdateEvent(
ConsentEvent(
startConsentEventTime,
timeHelper.now(),
currentConsentTab.asEventPayload(),
result
)
)
}

private fun getExitFormFromModalities(modalities: List<GeneralConfiguration.Modality>) = when {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.simprints.feature.consent.screens.consent

import com.simprints.feature.consent.screens.consent.helpers.GeneralConsentTextHelper
import com.simprints.feature.consent.screens.consent.helpers.ParentalConsentTextHelper

internal data class ConsentViewState(
val showLogo: Boolean = true,
val consentText: String = "",
val showParentalConsent: Boolean = false,
val parentalConsentText: String = "",
val selectedTab: Int = 0
val consentTextBuilder: GeneralConsentTextHelper? = null,
val parentalTextBuilder: ParentalConsentTextHelper? = null,
val selectedTab: Int = 0,
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,39 @@ package com.simprints.feature.consent.screens.consent.helpers
import android.content.Context
import com.simprints.feature.consent.ConsentType
import com.simprints.infra.config.store.models.ConsentConfiguration
import com.simprints.infra.config.store.models.GeneralConfiguration
import com.simprints.infra.config.store.models.GeneralConfiguration.*
import com.simprints.infra.resources.R
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject

internal class GeneralConsentTextHelper @Inject constructor(
@ApplicationContext val context: Context,
internal data class GeneralConsentTextHelper(
private val config: ConsentConfiguration,
private val modalities: List<Modality>,
private val consentType: ConsentType,
) {
// TODO All the `getString(id).format(arg,arg)` calls should be `getString(id,arg,arg)` one strings are fixed

//First argument in consent text should always be program name, second is modality specific access/use case text
fun assembleText(
config: ConsentConfiguration,
modalities: List<GeneralConfiguration.Modality>,
consentType: ConsentType,
) = StringBuilder().apply {
val modalityUseCase = getModalitySpecificUseCaseText(modalities)
val modalityAccess = getModalitySpecificAccessText(modalities)
fun assembleText(context: Context) = StringBuilder().apply {
val modalityUseCase = getModalitySpecificUseCaseText(context, modalities)
val modalityAccess = getModalitySpecificAccessText(context, modalities)

filterAppRequestForConsent(consentType, config, modalityUseCase)
filterForDataSharingOptions(config, modalityUseCase, modalityAccess)
filterAppRequestForConsent(context, consentType, config, modalityUseCase)
filterForDataSharingOptions(context, config, modalityUseCase, modalityAccess)
}.toString()

private fun StringBuilder.filterAppRequestForConsent(
context: Context,
consentType: ConsentType,
config: ConsentConfiguration,
modalityUseCase: String,
) {
when (consentType) {
ConsentType.ENROL -> appendTextForConsentEnrol(config.generalPrompt, config.programName, modalityUseCase)
ConsentType.IDENTIFY, ConsentType.VERIFY -> appendTextForConsentVerifyOrIdentify(config.programName, modalityUseCase)
ConsentType.ENROL -> appendTextForConsentEnrol(context, config.generalPrompt, config.programName, modalityUseCase)
ConsentType.IDENTIFY, ConsentType.VERIFY -> appendTextForConsentVerifyOrIdentify(context, config.programName, modalityUseCase)
}
}

private fun StringBuilder.appendTextForConsentEnrol(
context: Context,
config: ConsentConfiguration.ConsentPromptConfiguration?,
programName: String,
modalityUseCase: String,
Expand All @@ -53,11 +51,16 @@ internal class GeneralConsentTextHelper @Inject constructor(
else -> this
}

private fun StringBuilder.appendTextForConsentVerifyOrIdentify(programName: String, modalityUseCase: String) = appendSentence(
private fun StringBuilder.appendTextForConsentVerifyOrIdentify(
context: Context,
programName: String,
modalityUseCase: String
) = appendSentence(
context.getString(R.string.consent_id_verify).format(programName, modalityUseCase)
)

private fun StringBuilder.filterForDataSharingOptions(
context: Context,
config: ConsentConfiguration,
modalityUseCase: String,
modalityAccess: String,
Expand Down Expand Up @@ -86,33 +89,46 @@ internal class GeneralConsentTextHelper @Inject constructor(
}
}

private fun getModalitySpecificUseCaseText(modalities: List<GeneralConfiguration.Modality>) = if (modalities.size == 1) {
getSingleModalitySpecificUseCaseText(modalities)
private fun getModalitySpecificUseCaseText(
context: Context,
modalities: List<Modality>,
) = if (modalities.size == 1) {
getSingleModalitySpecificUseCaseText(context, modalities)
} else {
getConcatenatedModalitiesUseCaseText()
getConcatenatedModalitiesUseCaseText(context)
}

private fun getConcatenatedModalitiesUseCaseText() = "%s %s %s".format(
private fun getConcatenatedModalitiesUseCaseText(context: Context) = "%s %s %s".format(
context.getString(R.string.consent_biometrics_general_fingerprint),
context.getString(R.string.consent_biometric_concat_modalities),
context.getString(R.string.consent_biometric_general_face)
)

private fun getSingleModalitySpecificUseCaseText(modalities: List<GeneralConfiguration.Modality>) = when (modalities.first()) {
GeneralConfiguration.Modality.FACE -> context.getString(R.string.consent_biometric_general_face)
GeneralConfiguration.Modality.FINGERPRINT -> context.getString(R.string.consent_biometrics_general_fingerprint)
private fun getSingleModalitySpecificUseCaseText(
context: Context,
modalities: List<Modality>,
) = when (modalities.first()) {
Modality.FACE -> context.getString(R.string.consent_biometric_general_face)
Modality.FINGERPRINT -> context.getString(R.string.consent_biometrics_general_fingerprint)
}

private fun getModalitySpecificAccessText(modalities: List<GeneralConfiguration.Modality>) = if (modalities.size == 1) {
getSingleModalityAccessText(modalities)
private fun getModalitySpecificAccessText(
context: Context,
modalities: List<Modality>,
) = if (modalities.size == 1) {
getSingleModalityAccessText(context, modalities)
} else {
getConcatenatedModalitiesAccessText()
getConcatenatedModalitiesAccessText(context)
}

private fun getConcatenatedModalitiesAccessText() = context.getString(R.string.consent_biometrics_access_fingerprint_face)
private fun getConcatenatedModalitiesAccessText(context: Context) =
context.getString(R.string.consent_biometrics_access_fingerprint_face)

private fun getSingleModalityAccessText(modalities: List<GeneralConfiguration.Modality>) = when (modalities.first()) {
GeneralConfiguration.Modality.FACE -> context.getString(R.string.consent_biometrics_access_face)
GeneralConfiguration.Modality.FINGERPRINT -> context.getString(R.string.consent_biometrics_access_fingerprint)
private fun getSingleModalityAccessText(
context: Context,
modalities: List<Modality>,
) = when (modalities.first()) {
Modality.FACE -> context.getString(R.string.consent_biometrics_access_face)
Modality.FINGERPRINT -> context.getString(R.string.consent_biometrics_access_fingerprint)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,37 @@ import com.simprints.feature.consent.ConsentType
import com.simprints.infra.config.store.models.ConsentConfiguration
import com.simprints.infra.config.store.models.GeneralConfiguration.Modality
import com.simprints.infra.resources.R
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject

internal class ParentalConsentTextHelper @Inject constructor(
@ApplicationContext val context: Context
internal data class ParentalConsentTextHelper(
private val config: ConsentConfiguration,
private val modalities: List<Modality>,
private val consentType: ConsentType,
) {
// TODO All the `getString(id).format(arg,arg)` calls should be `getString(id,arg,arg)` one strings are fixed

//First argument in consent text should always be program name, second is modality specific access/use case text
fun assembleText(
config: ConsentConfiguration,
modalities: List<Modality>,
consentType: ConsentType,
): String = StringBuilder().apply {
val modalityUseCase = getModalitySpecificUseCaseText(modalities)
val modalityAccess = getModalitySpecificAccessText(modalities)
fun assembleText(context: Context): String = StringBuilder().apply {
val modalityUseCase = getModalitySpecificUseCaseText(context, modalities)
val modalityAccess = getModalitySpecificAccessText(context, modalities)

filterAppRequestForParentalConsent(consentType, config, modalityUseCase)
extractDataSharingOptions(config, modalityUseCase, modalityAccess)
filterAppRequestForParentalConsent(context, consentType, config, modalityUseCase)
extractDataSharingOptions(context, config, modalityUseCase, modalityAccess)
}.toString()

private fun StringBuilder.filterAppRequestForParentalConsent(
context: Context,
consentType: ConsentType,
config: ConsentConfiguration,
modalityUseCase: String,
) {
when (consentType) {
ConsentType.ENROL -> appendTextForParentalEnrol(config.parentalPrompt, config.programName, modalityUseCase)
ConsentType.IDENTIFY, ConsentType.VERIFY -> appendTextForIdentifyOrVerify(config.programName, modalityUseCase)
ConsentType.ENROL -> appendTextForParentalEnrol(context, config.parentalPrompt, config.programName, modalityUseCase)
ConsentType.IDENTIFY, ConsentType.VERIFY -> appendTextForIdentifyOrVerify(context, config.programName, modalityUseCase)
}
}

private fun StringBuilder.appendTextForParentalEnrol(
context: Context,
config: ConsentConfiguration.ConsentPromptConfiguration?,
programName: String,
modalityUseCase: String,
Expand All @@ -55,11 +53,16 @@ internal class ParentalConsentTextHelper @Inject constructor(
else -> this
}

private fun StringBuilder.appendTextForIdentifyOrVerify(programName: String, modalityUseCase: String) = appendSentence(
private fun StringBuilder.appendTextForIdentifyOrVerify(
context: Context,
programName: String,
modalityUseCase: String,
) = appendSentence(
context.getString(R.string.consent_parental_id_verify).format(programName, modalityUseCase)
)

private fun StringBuilder.extractDataSharingOptions(
context: Context,
config: ConsentConfiguration,
modalityUseCase: String,
modalityAccess: String
Expand All @@ -86,33 +89,46 @@ internal class ParentalConsentTextHelper @Inject constructor(
}
}

private fun getModalitySpecificUseCaseText(modalities: List<Modality>) = if (modalities.size == 1) {
getSingleModalitySpecificUseCaseText(modalities)
private fun getModalitySpecificUseCaseText(
context: Context,
modalities: List<Modality>,
) = if (modalities.size == 1) {
getSingleModalitySpecificUseCaseText(context, modalities)
} else {
getConcatenatedModalitiesUseCaseText()
getConcatenatedModalitiesUseCaseText(context)
}

private fun getConcatenatedModalitiesUseCaseText() = "%s %s %s".format(
private fun getConcatenatedModalitiesUseCaseText(context: Context) = "%s %s %s".format(
context.getString(R.string.consent_biometrics_parental_fingerprint),
context.getString(R.string.consent_biometric_concat_modalities),
context.getString(R.string.consent_biometrics_parental_face)
)

private fun getSingleModalitySpecificUseCaseText(modalities: List<Modality>) = when (modalities.first()) {
private fun getSingleModalitySpecificUseCaseText(
context: Context,
modalities: List<Modality>,
) = when (modalities.first()) {
Modality.FACE -> context.getString(R.string.consent_biometrics_parental_face)
Modality.FINGERPRINT -> context.getString(R.string.consent_biometrics_parental_fingerprint)
else -> ""
}

private fun getModalitySpecificAccessText(modalities: List<Modality>) = if (modalities.size == 1) {
getSingleModalityAccessText(modalities)
private fun getModalitySpecificAccessText(
context: Context,
modalities: List<Modality>,
) = if (modalities.size == 1) {
getSingleModalityAccessText(context, modalities)
} else {
getConcatenatedModalitiesAccessText()
getConcatenatedModalitiesAccessText(context)
}

private fun getConcatenatedModalitiesAccessText() = context.getString(R.string.consent_biometrics_access_fingerprint_face)
private fun getConcatenatedModalitiesAccessText(context: Context) =
context.getString(R.string.consent_biometrics_access_fingerprint_face)

private fun getSingleModalityAccessText(modalities: List<Modality>) = when (modalities.first()) {
private fun getSingleModalityAccessText(
context: Context,
modalities: List<Modality>,
) = when (modalities.first()) {
Modality.FACE -> context.getString(R.string.consent_biometrics_access_face)
Modality.FINGERPRINT -> context.getString(R.string.consent_biometrics_access_fingerprint)
else -> ""
Expand Down
Loading