feat(CON-265) : Aligner les flux de l'api d'UI avec les nouveaux dev back
This commit is contained in:
parent
c57c9b7d05
commit
af91841857
@ -3,12 +3,14 @@ import androidx.compose.animation.slideIn
|
||||
import androidx.compose.animation.slideOut
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.toRoute
|
||||
import fr.openium.consentium.R
|
||||
import fr.openium.consentium.api.Consentium
|
||||
import fr.openium.consentium.ui.screens.main.MainScreen
|
||||
import fr.openium.consentium.ui.screens.splash.SplashScreen
|
||||
@ -79,6 +81,9 @@ fun DemoNavGraph(navHostController: NavHostController) {
|
||||
composable<Destination.Consent> { backStackEntry ->
|
||||
val consent = backStackEntry.toRoute<Destination.Consent>()
|
||||
|
||||
val appId = stringResource(R.string.app_id)
|
||||
val apiKey = stringResource(R.string.api_key)
|
||||
|
||||
val context = LocalContext.current
|
||||
ConsentiumComponent(
|
||||
defaultLandingPage = consent.landingPage,
|
||||
@ -91,7 +96,8 @@ fun DemoNavGraph(navHostController: NavHostController) {
|
||||
},
|
||||
consentium = Consentium(
|
||||
context = context,
|
||||
applicationId = "ApplicationId",
|
||||
apiKey = apiKey,
|
||||
appId = appId,
|
||||
),
|
||||
colors = ConsentiumDefaults.colors(
|
||||
primary = Primary,
|
||||
|
@ -27,8 +27,9 @@ fun SplashScreen(
|
||||
) {
|
||||
// Property
|
||||
val context = LocalContext.current
|
||||
val consentiumKey = stringResource(R.string.consentium_api_key)
|
||||
val consentium = remember { Consentium(context = context, applicationId = consentiumKey) }
|
||||
val apiKey = stringResource(R.string.api_key)
|
||||
val appId = stringResource(R.string.app_id)
|
||||
val consentium = remember { Consentium(context = context, apiKey = apiKey, appId = appId) }
|
||||
|
||||
// Effect
|
||||
LaunchedEffect(Unit) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
<resources>
|
||||
<string name="app_name">Consentium</string>
|
||||
<string translatable="false" name="consentium_api_key">01938ce4-331a-7592-9e90-f09201ff4f36</string>
|
||||
<string name="app_id" translatable="false">01938ce4-331a-7592-9e90-f09201ff4f36</string>
|
||||
<string name="api_key" translatable="false">c452a27f-2e90-427d-be82-2f631c31dd09</string>
|
||||
</resources>
|
@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
</manifest>
|
@ -3,13 +3,15 @@ package fr.openium.consentium_ui.data.remote
|
||||
import fr.openium.consentium_ui.data.remote.model.GetConsentConfigDTO
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Header
|
||||
import retrofit2.http.Path
|
||||
|
||||
internal interface ConsentiumUIApi {
|
||||
|
||||
@GET("consent-config")
|
||||
@GET("applications/{application}")
|
||||
suspend fun getConsentConfig(
|
||||
applicationID: String,
|
||||
installationID: String,
|
||||
@Header("Authorization") token: String,
|
||||
@Path("application") applicationId: String,
|
||||
): Response<GetConsentConfigDTO>
|
||||
|
||||
}
|
@ -6,8 +6,6 @@ import fr.openium.consentium_ui.data.remote.model.MainConsentTextTranslationDTO
|
||||
import fr.openium.consentium_ui.data.remote.model.PurposeDTO
|
||||
import fr.openium.consentium_ui.data.remote.model.PurposeStatusDTO
|
||||
import fr.openium.consentium_ui.data.remote.model.PurposeTranslationDTO
|
||||
import fr.openium.consentium_ui.data.remote.model.VendorDTO
|
||||
import fr.openium.consentium_ui.data.remote.model.VendorTranslationDTO
|
||||
import retrofit2.Response
|
||||
import java.util.UUID
|
||||
|
||||
@ -17,9 +15,6 @@ internal object ConsentiumUIMockApi : ConsentiumUIApi {
|
||||
installationId = UUID.randomUUID().toString(),
|
||||
appName = "Consentium",
|
||||
icon = "https://amp.openium.fr/openium.png",
|
||||
primaryColor = "#FF0000",
|
||||
secondaryColor = "#00FF00",
|
||||
textColor = "#0000FF",
|
||||
consentMainTextTranslation = listOf(
|
||||
MainConsentTextTranslationDTO(
|
||||
id = "UUID",
|
||||
@ -29,12 +24,13 @@ internal object ConsentiumUIMockApi : ConsentiumUIApi {
|
||||
durationText = "<p>Nous conservons votre choix pendant 12 mois. Vous pouvez changer d’avis à tout moment depuis les paramètres de votre compte via l’onglet “Notification et cookies” tetetettetettetetstts</p>\n"
|
||||
)
|
||||
),
|
||||
consentPageUrl = "https://www.openium.fr",
|
||||
purposes = listOf(
|
||||
PurposeDTO(
|
||||
id = "purpose-required",
|
||||
order = 0,
|
||||
isRequired = true,
|
||||
isAccepted = PurposeStatusDTO.ACCEPTED,
|
||||
choice = PurposeStatusDTO.ACCEPTED,
|
||||
translations = listOf(
|
||||
PurposeTranslationDTO(
|
||||
id = "UUID",
|
||||
@ -43,40 +39,12 @@ internal object ConsentiumUIMockApi : ConsentiumUIApi {
|
||||
name = "Nécessaire"
|
||||
)
|
||||
),
|
||||
vendors = listOf(
|
||||
VendorDTO(
|
||||
id = "vendors-crashlytics",
|
||||
order = 0,
|
||||
isAccepted = true,
|
||||
isRequired = true,
|
||||
translations = listOf(
|
||||
VendorTranslationDTO(
|
||||
id = "UUID",
|
||||
language = "fr",
|
||||
text = "<p>Ces traceurs sont nécessaire au fonctionnement de l’application. Ils permettent de vérifier la stabilité technique de l’application et de mesurer notre audience. Ces données ne sont utilisées que pour notre compte exclusif (en ne produisant que des données statistiques anonymes).</p>"
|
||||
)
|
||||
)
|
||||
),
|
||||
VendorDTO(
|
||||
id = "vendors-matomo",
|
||||
order = 1,
|
||||
isAccepted = true,
|
||||
isRequired = false,
|
||||
translations = listOf(
|
||||
VendorTranslationDTO(
|
||||
id = "UUID",
|
||||
language = "fr",
|
||||
text = "<p>Ces traceurs sont nécessaire au fonctionnement de l’application. Ils permettent de vérifier la stabilité technique de l’application et de mesurer notre audience. Ces données ne sont utilisées que pour notre compte exclusif (en ne produisant que des données statistiques anonymes).</p>"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
PurposeDTO(
|
||||
id = "purpose-advertising",
|
||||
order = 1,
|
||||
isRequired = false,
|
||||
isAccepted = PurposeStatusDTO.REJECTED,
|
||||
choice = PurposeStatusDTO.REFUSED,
|
||||
translations = listOf(
|
||||
PurposeTranslationDTO(
|
||||
id = "UUID",
|
||||
@ -85,27 +53,12 @@ internal object ConsentiumUIMockApi : ConsentiumUIApi {
|
||||
name = "Publicité"
|
||||
)
|
||||
),
|
||||
vendors = listOf(
|
||||
VendorDTO(
|
||||
id = "vendors-admob",
|
||||
order = 0,
|
||||
isAccepted = true,
|
||||
isRequired = false,
|
||||
translations = listOf(
|
||||
VendorTranslationDTO(
|
||||
id = "UUID",
|
||||
language = "fr",
|
||||
text = "<p>Ces traceurs sont nécessaires pour afficher des publicités susceptibles de vous intéresser. Ils permettent de mesurer l’efficacité de nos campagnes publicitaires et de personnaliser les publicités affichées.</p>"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
PurposeDTO(
|
||||
id = "purpose-analytics",
|
||||
order = 2,
|
||||
isRequired = false,
|
||||
isAccepted = PurposeStatusDTO.ACCEPTED,
|
||||
choice = PurposeStatusDTO.ACCEPTED,
|
||||
translations = listOf(
|
||||
PurposeTranslationDTO(
|
||||
id = "UUID",
|
||||
@ -114,27 +67,12 @@ internal object ConsentiumUIMockApi : ConsentiumUIApi {
|
||||
name = "Analyse"
|
||||
)
|
||||
),
|
||||
vendors = listOf(
|
||||
VendorDTO(
|
||||
id = "vendors-firebase",
|
||||
order = 0,
|
||||
isAccepted = true,
|
||||
isRequired = false,
|
||||
translations = listOf(
|
||||
VendorTranslationDTO(
|
||||
id = "UUID",
|
||||
language = "fr",
|
||||
text = "<p>Ces traceurs sont nécessaires pour mesurer l’efficacité de nos contenus. Ils permettent de mesurer l’audience de l’application et de comprendre comment les utilisateurs interagissent avec l’application.</p>"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
PurposeDTO(
|
||||
id = "purpose-personalization",
|
||||
order = 3,
|
||||
isRequired = false,
|
||||
isAccepted = PurposeStatusDTO.ACCEPTED,
|
||||
choice = PurposeStatusDTO.ACCEPTED,
|
||||
translations = listOf(
|
||||
PurposeTranslationDTO(
|
||||
id = "UUID",
|
||||
@ -143,27 +81,12 @@ internal object ConsentiumUIMockApi : ConsentiumUIApi {
|
||||
name = "Personnalisation"
|
||||
)
|
||||
),
|
||||
vendors = listOf(
|
||||
VendorDTO(
|
||||
id = "vendors-firebase",
|
||||
order = 0,
|
||||
isAccepted = true,
|
||||
isRequired = false,
|
||||
translations = listOf(
|
||||
VendorTranslationDTO(
|
||||
id = "UUID",
|
||||
language = "fr",
|
||||
text = "<p>Ces traceurs sont nécessaires pour mesurer l’efficacité de nos contenus. Ils permettent de mesurer l’audience de l’application et de comprendre comment les utilisateurs interagissent avec l’application.</p>"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
PurposeDTO(
|
||||
id = "purpose-social",
|
||||
order = 4,
|
||||
isRequired = false,
|
||||
isAccepted = PurposeStatusDTO.ACCEPTED,
|
||||
choice = PurposeStatusDTO.ACCEPTED,
|
||||
translations = listOf(
|
||||
PurposeTranslationDTO(
|
||||
id = "UUID",
|
||||
@ -172,28 +95,13 @@ internal object ConsentiumUIMockApi : ConsentiumUIApi {
|
||||
name = "Social"
|
||||
)
|
||||
),
|
||||
vendors = listOf(
|
||||
VendorDTO(
|
||||
id = "vendors-firebase",
|
||||
order = 0,
|
||||
isAccepted = true,
|
||||
isRequired = false,
|
||||
translations = listOf(
|
||||
VendorTranslationDTO(
|
||||
id = "UUID",
|
||||
language = "fr",
|
||||
text = "<p>Ces traceurs sont nécessaires pour mesurer l’efficacité de nos contenus. Ils permettent de mesurer l’audience de l’application et de comprendre comment les utilisateurs interagissent avec l’application.</p>"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
override suspend fun getConsentConfig(
|
||||
applicationID: String,
|
||||
installationID: String,
|
||||
token: String,
|
||||
applicationId: String,
|
||||
): Response<GetConsentConfigDTO> {
|
||||
return Response.success(consents)
|
||||
}
|
||||
|
@ -7,10 +7,8 @@ import kotlinx.serialization.Serializable
|
||||
internal data class GetConsentConfigDTO(
|
||||
@SerialName("id") val installationId: String,
|
||||
@SerialName("name") val appName: String,
|
||||
@SerialName("icon") val icon: String,
|
||||
@SerialName("primaryColor") val primaryColor: String,
|
||||
@SerialName("secondaryColor") val secondaryColor: String,
|
||||
@SerialName("textColor") val textColor: String,
|
||||
@SerialName("translation") val consentMainTextTranslation: List<MainConsentTextTranslationDTO>,
|
||||
@SerialName("icon") val icon: String? = null,
|
||||
@SerialName("consentPageUrl") val consentPageUrl: String,
|
||||
@SerialName("translations") val consentMainTextTranslation: List<MainConsentTextTranslationDTO>,
|
||||
@SerialName("purposes") val purposes: List<PurposeDTO>,
|
||||
)
|
@ -7,7 +7,8 @@ import kotlinx.serialization.Serializable
|
||||
internal data class MainConsentTextTranslationDTO(
|
||||
@SerialName("id") val id: String,
|
||||
@SerialName("lang") val language: String,
|
||||
@SerialName("consentPageUrl") val consentPageUrl: String,
|
||||
@SerialName("mainConsentText") val mainConsentText: String,
|
||||
@SerialName("durationText") val durationText: String,
|
||||
@SerialName("consentPageUrl") val consentPageUrl: String,
|
||||
|
||||
)
|
@ -5,10 +5,10 @@ import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
internal data class PurposeDTO(
|
||||
@SerialName("identifier") val id: String,
|
||||
@SerialName("order") val order: Int,
|
||||
@SerialName("sortOrder") val order: Int,
|
||||
@SerialName("isRequired") val isRequired: Boolean,
|
||||
@SerialName("isAccepted") val isAccepted: PurposeStatusDTO,
|
||||
@SerialName("choice") val choice: PurposeStatusDTO,
|
||||
@SerialName("translations") val translations: List<PurposeTranslationDTO>,
|
||||
@SerialName("vendors") val vendors: List<VendorDTO>,
|
||||
@SerialName("identifier") val id: String,
|
||||
|
||||
)
|
||||
|
@ -5,12 +5,12 @@ import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
internal enum class PurposeStatusDTO {
|
||||
@SerialName("ACCEPTED")
|
||||
@SerialName("accepted")
|
||||
ACCEPTED,
|
||||
|
||||
@SerialName("REJECTED")
|
||||
REJECTED,
|
||||
@SerialName("refused")
|
||||
REFUSED,
|
||||
|
||||
@SerialName("NOT_DEFINED")
|
||||
NOT_DEFINED,
|
||||
@SerialName("partial")
|
||||
PARTIAL,
|
||||
}
|
@ -7,9 +7,9 @@ internal fun PurposeDTO.toPurposeData() =
|
||||
PurposeData(
|
||||
identifier = id,
|
||||
isRequired = isRequired,
|
||||
isAccepted = isAccepted.toPurposeStatusData(),
|
||||
choice = choice.toPurposeStatusData(),
|
||||
order = order,
|
||||
vendors = vendors.toVendorDataList(),
|
||||
vendors = emptyList(),
|
||||
translations = translations.toPurposeTranslationDataList(),
|
||||
)
|
||||
|
||||
|
@ -6,7 +6,7 @@ import fr.openium.consentium_ui.domain.model.PurposeStatusData
|
||||
internal fun PurposeStatusDTO.toPurposeStatusData(): PurposeStatusData {
|
||||
return when (this) {
|
||||
PurposeStatusDTO.ACCEPTED -> PurposeStatusData.ACCEPTED
|
||||
PurposeStatusDTO.REJECTED -> PurposeStatusData.REJECTED
|
||||
PurposeStatusDTO.NOT_DEFINED -> PurposeStatusData.NOT_DEFINED
|
||||
PurposeStatusDTO.REFUSED -> PurposeStatusData.REJECTED
|
||||
PurposeStatusDTO.PARTIAL -> PurposeStatusData.PARTIAL
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package fr.openium.consentium_ui.domain.model
|
||||
|
||||
internal data class ContentConfigData(
|
||||
val applicationName: String,
|
||||
val iconUrl : String,
|
||||
val iconUrl : String?,
|
||||
val mainTextTranslation: List<MainConsentTextTranslationData>,
|
||||
val purposes: List<PurposeData>
|
||||
)
|
||||
|
@ -4,7 +4,7 @@ internal data class PurposeData(
|
||||
val identifier: String,
|
||||
val order: Int,
|
||||
val isRequired: Boolean,
|
||||
val isAccepted: PurposeStatusData,
|
||||
val choice: PurposeStatusData,
|
||||
val translations: List<PurposeTranslationData>,
|
||||
val vendors: List<VendorData>,
|
||||
)
|
||||
|
@ -3,5 +3,5 @@ package fr.openium.consentium_ui.domain.model
|
||||
internal enum class PurposeStatusData {
|
||||
ACCEPTED,
|
||||
REJECTED,
|
||||
NOT_DEFINED,
|
||||
PARTIAL,
|
||||
}
|
@ -1,22 +1,23 @@
|
||||
package fr.openium.consentium_ui.domain.repository
|
||||
|
||||
import fr.openium.consentium.domain.useCase.GetConsentiumUniqueInstallationIdUseCase
|
||||
import fr.openium.consentium.domain.useCase.GetAuthTokenUseCase
|
||||
import fr.openium.consentium_ui.data.remote.ConsentiumUIApi
|
||||
import fr.openium.consentium_ui.domain.adapter.toConsentConfigData
|
||||
import fr.openium.consentium_ui.domain.model.ContentConfigData
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class ConsentiumRepository @Inject constructor(
|
||||
private val getConsentiumUniqueInstallationIdUseCase: GetConsentiumUniqueInstallationIdUseCase,
|
||||
private val consentiumUIApi: ConsentiumUIApi,
|
||||
private val getAuthTokenUseCase: GetAuthTokenUseCase,
|
||||
) {
|
||||
suspend fun getConsentiumConfig(
|
||||
applicationId: String,
|
||||
apiKey: String,
|
||||
): ConsentiumUIRepositoryResponse {
|
||||
val installationId = getConsentiumUniqueInstallationIdUseCase.invoke()
|
||||
val consentsResponse = consentiumUIApi.getConsentConfig(applicationId, installationId)
|
||||
|
||||
return try {
|
||||
val authToken = getAuthTokenUseCase(apiKey)
|
||||
val consentsResponse = consentiumUIApi.getConsentConfig(authToken, applicationId)
|
||||
val consentsBody = if (consentsResponse.isSuccessful) {
|
||||
consentsResponse.body() ?: throw Exception()
|
||||
} else {
|
||||
@ -25,10 +26,10 @@ internal class ConsentiumRepository @Inject constructor(
|
||||
|
||||
ConsentiumUIRepositoryResponse.Success(consentsBody.toConsentConfigData())
|
||||
} catch (e: Exception) {
|
||||
Timber.d("$e")
|
||||
ConsentiumUIRepositoryResponse.Error
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal interface ConsentiumUIRepositoryResponse {
|
||||
|
@ -27,6 +27,7 @@ internal fun ConsentiumScreen(
|
||||
onSaveAndCloseDetails: (consents: DetailConsentUI) -> Unit,
|
||||
onNavigateToDetails: () -> Unit,
|
||||
onClickCookiesPolicies: () -> Unit,
|
||||
onClickRetry: () -> Unit,
|
||||
) {
|
||||
when (state) {
|
||||
is ConsentiumUIState.Loading -> {
|
||||
@ -36,6 +37,7 @@ internal fun ConsentiumScreen(
|
||||
is ConsentiumUIState.Error -> {
|
||||
ConsentiumUIErrorComponent(
|
||||
errorMessage = state.message,
|
||||
onRetry = onClickRetry
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import fr.openium.consentium_ui.R
|
||||
import fr.openium.consentium_ui.domain.repository.ConsentiumRepository
|
||||
import fr.openium.consentium_ui.domain.repository.ConsentiumUIRepositoryResponse
|
||||
import fr.openium.consentium_ui.domain.usecase.GetApplicationLanguageUseCase
|
||||
@ -30,12 +31,12 @@ internal class ConsentiumUIViewModel @Inject constructor(
|
||||
private val _state = MutableStateFlow<ConsentiumUIState>(ConsentiumUIState.Loading)
|
||||
val state: StateFlow<ConsentiumUIState> by lazy { _state.asStateFlow() }
|
||||
|
||||
fun init(appId: String) {
|
||||
fun init(appId: String, apiKey: String) {
|
||||
viewModelScope.launch {
|
||||
|
||||
_state.value = ConsentiumUIState.Loading
|
||||
|
||||
when (val consentiumUIFetchResponse = consentiumUIRepository.getConsentiumConfig(appId)) {
|
||||
when (val consentiumUIFetchResponse = consentiumUIRepository.getConsentiumConfig(appId, apiKey)) {
|
||||
|
||||
is ConsentiumUIRepositoryResponse.Success -> {
|
||||
val consentUIResponse =
|
||||
@ -44,28 +45,32 @@ internal class ConsentiumUIViewModel @Inject constructor(
|
||||
when (val consentUI = consentUIResponse) {
|
||||
|
||||
is GetConfigTextForLanguageUseCaseResponse.Success -> {
|
||||
_state.emit(ConsentiumUIState.Loaded(
|
||||
_state.emit(
|
||||
ConsentiumUIState.Loaded(
|
||||
generalConsentUI = consentUI.configData.toGeneralConsentUI(),
|
||||
detailConsentUI = consentUI.configData.toDetailConsentUI(),
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
is GetConfigTextForLanguageUseCaseResponse.DefaultLanguage -> {
|
||||
_state.emit(ConsentiumUIState.Loaded(
|
||||
_state.emit(
|
||||
ConsentiumUIState.Loaded(
|
||||
generalConsentUI = consentUI.configData.toGeneralConsentUI(),
|
||||
detailConsentUI = consentUI.configData.toDetailConsentUI(),
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
is GetConfigTextForLanguageUseCaseResponse.Error -> {
|
||||
_state.emit(ConsentiumUIState.Error("Failed to load data"))
|
||||
_state.emit(ConsentiumUIState.Error(context.getString(R.string.consents_error_loading_consents)))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
is ConsentiumUIRepositoryResponse.Error -> {
|
||||
_state.value = ConsentiumUIState.Error("Failed to load data")
|
||||
_state.value = ConsentiumUIState.Error(context.getString(R.string.consents_error_loading_consents))
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package fr.openium.consentium_ui.ui.adapter
|
||||
|
||||
import fr.openium.consentium.api.model.PurposeChoice
|
||||
import fr.openium.consentium.api.model.PurposeStatus
|
||||
import fr.openium.consentium_ui.domain.model.ContentConfigData
|
||||
import fr.openium.consentium_ui.ui.model.DetailConsentUI
|
||||
import fr.openium.consentium_ui.ui.model.PurposeStatusUI
|
||||
@ -17,16 +18,23 @@ internal fun DetailConsentUI.toPurposeChoices(): List<PurposeChoice> = purposes.
|
||||
}
|
||||
|
||||
internal fun DetailConsentUI.toDeniedPurposeChoices(): List<PurposeChoice> = purposes.map {
|
||||
it.toPurposeChoice().copy(isAccepted = false)
|
||||
it.toPurposeChoice().copy(choice = PurposeStatus.REJECTED)
|
||||
}
|
||||
|
||||
internal fun DetailConsentUI.toAcceptedPurposeChoices(): List<PurposeChoice> = purposes.map {
|
||||
it.toPurposeChoice().copy(isAccepted = true)
|
||||
it.toPurposeChoice().copy(choice = PurposeStatus.ACCEPTED)
|
||||
}
|
||||
|
||||
internal fun PurposeUI.toPurposeChoice(): PurposeChoice =
|
||||
PurposeChoice(
|
||||
purposeIdentifier = id,
|
||||
isAccepted = isAccepted == PurposeStatusUI.ACCEPTED,
|
||||
choice = choice.toPurposeStatus(),
|
||||
vendors = emptyList(), // Not in v1
|
||||
)
|
||||
|
||||
internal fun PurposeStatusUI.toPurposeStatus(): PurposeStatus =
|
||||
when (this) {
|
||||
PurposeStatusUI.ACCEPTED -> PurposeStatus.ACCEPTED
|
||||
PurposeStatusUI.REJECTED -> PurposeStatus.REJECTED
|
||||
PurposeStatusUI.PARTIAL -> PurposeStatus.PARTIAL
|
||||
}
|
@ -6,5 +6,5 @@ import fr.openium.consentium_ui.ui.model.PurposeStatusUI
|
||||
internal fun PurposeStatusData.toPurposeStatusUI(): PurposeStatusUI = when(this) {
|
||||
PurposeStatusData.ACCEPTED -> PurposeStatusUI.ACCEPTED
|
||||
PurposeStatusData.REJECTED -> PurposeStatusUI.REJECTED
|
||||
PurposeStatusData.NOT_DEFINED -> PurposeStatusUI.NOT_DEFINED
|
||||
PurposeStatusData.PARTIAL -> PurposeStatusUI.PARTIAL
|
||||
}
|
@ -6,7 +6,7 @@ import fr.openium.consentium_ui.ui.model.PurposeUI
|
||||
internal fun PurposeData.toPurposeUI(): PurposeUI = PurposeUI(
|
||||
id = identifier,
|
||||
isRequired = isRequired,
|
||||
isAccepted = isAccepted.toPurposeStatusUI(),
|
||||
choice = choice.toPurposeStatusUI(),
|
||||
title = translations.first().name,
|
||||
description = translations.first().text,
|
||||
vendors = vendors.toVendorUIList(),
|
||||
|
@ -51,7 +51,7 @@ fun ConsentiumComponent(
|
||||
|
||||
// Effect
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.init(consentium.applicationId)
|
||||
viewModel.init(apiKey = consentium.apiKey, appId = consentium.appId)
|
||||
}
|
||||
|
||||
LaunchedEffect(consentiumState) {
|
||||
@ -131,6 +131,9 @@ fun ConsentiumComponent(
|
||||
onClickCookiesPolicies = {
|
||||
currentPage = ConsentiumPageUI.COOKIES_POLICY
|
||||
},
|
||||
onClickRetry = {
|
||||
viewModel.init(apiKey = consentium.apiKey, appId = consentium.appId)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -2,19 +2,31 @@ package fr.openium.consentium_ui.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import fr.openium.consentium_ui.R
|
||||
import fr.openium.consentium_ui.ui.components.core.button.ConsentButton
|
||||
import fr.openium.consentium_ui.ui.components.core.button.ConsentiumUIButtonStyle
|
||||
import fr.openium.consentium_ui.ui.components.style.ConsentiumUITheme
|
||||
|
||||
@Composable
|
||||
internal fun ConsentiumUIErrorComponent(
|
||||
errorMessage: String,
|
||||
onRetry: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = 24.dp),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
@ -22,6 +34,15 @@ internal fun ConsentiumUIErrorComponent(
|
||||
text = errorMessage,
|
||||
color = ConsentiumUITheme.colors.error,
|
||||
style = ConsentiumUITheme.typography.b2,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
ConsentButton(
|
||||
text = stringResource(R.string.retry),
|
||||
buttonStyle = ConsentiumUIButtonStyle.PRIMARY,
|
||||
onclick = onRetry,
|
||||
)
|
||||
}
|
||||
}
|
@ -28,7 +28,7 @@ internal fun PurposeComponent(
|
||||
purposeUI: PurposeUI,
|
||||
) {
|
||||
// Properties
|
||||
var isChecked by remember { mutableStateOf(purposeUI.isAccepted != PurposeStatusUI.REJECTED) }
|
||||
var isChecked by remember { mutableStateOf(purposeUI.choice != PurposeStatusUI.REJECTED) }
|
||||
|
||||
// View
|
||||
Column(
|
||||
@ -58,7 +58,7 @@ internal fun PurposeComponent(
|
||||
checked = isChecked,
|
||||
onCheckedChange = {
|
||||
isChecked = !isChecked
|
||||
purposeUI.isAccepted = if (isChecked) PurposeStatusUI.ACCEPTED else PurposeStatusUI.REJECTED
|
||||
purposeUI.choice = if (isChecked) PurposeStatusUI.ACCEPTED else PurposeStatusUI.REJECTED
|
||||
purposeUI.vendors.forEach { vendorUI ->
|
||||
vendorUI.isAccepted = isChecked
|
||||
}
|
||||
@ -95,7 +95,7 @@ private fun PurposeComponentPreview() {
|
||||
purposeUI = PurposeUI(
|
||||
id = "1",
|
||||
isRequired = true,
|
||||
isAccepted = PurposeStatusUI.ACCEPTED,
|
||||
choice = PurposeStatusUI.ACCEPTED,
|
||||
title = "Title",
|
||||
description = "Description",
|
||||
vendors = emptyList(),
|
||||
|
@ -2,7 +2,7 @@ package fr.openium.consentium_ui.ui.model
|
||||
|
||||
internal data class GeneralConsentUI(
|
||||
val applicationName: String,
|
||||
val iconUrl: String,
|
||||
val iconUrl: String?,
|
||||
val mainConsentText: String,
|
||||
val consentPageUrl: String,
|
||||
)
|
@ -3,5 +3,5 @@ package fr.openium.consentium_ui.ui.model
|
||||
internal enum class PurposeStatusUI {
|
||||
ACCEPTED,
|
||||
REJECTED,
|
||||
NOT_DEFINED,
|
||||
PARTIAL,
|
||||
}
|
@ -3,7 +3,7 @@ package fr.openium.consentium_ui.ui.model
|
||||
internal data class PurposeUI(
|
||||
val id: String,
|
||||
val isRequired: Boolean,
|
||||
var isAccepted: PurposeStatusUI,
|
||||
var choice: PurposeStatusUI,
|
||||
val title: String,
|
||||
val description: String,
|
||||
val vendors: List<VendorUI>,
|
||||
|
@ -6,5 +6,7 @@
|
||||
<string name="parameters">Paramétrer mes choix</string>
|
||||
<string name="save">Enregistrer et fermer</string>
|
||||
<string name="require">Requis</string>
|
||||
<string name="retry">Réessayer</string>
|
||||
<string name="save_consents_error_message">Une erreur est survenue l\'or de la ssauvegarde de vos consentements.</string>
|
||||
<string name="consents_error_loading_consents">Il y a eu une erreur lors du chargement de vos consentements</string>
|
||||
</resources>
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="backend_url" translatable="false" tools:ignore="UnusedResources">https://consentium-api-dev.openium.fr/api/v1/app</string>
|
||||
<resources>
|
||||
<string name="backend_url" translatable="false">https://consentium-api-dev.openium.fr/api/v1/app/</string>
|
||||
</resources>
|
@ -1,4 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
</manifest>
|
@ -15,7 +15,8 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
class Consentium(
|
||||
context: Context,
|
||||
val applicationId: String,
|
||||
val apiKey: String,
|
||||
val appId: String,
|
||||
) {
|
||||
private val _fetchConsentState = MutableStateFlow<FetchConsentiumState>(FetchConsentiumState.Idle)
|
||||
val fetchConsentState by lazy { _fetchConsentState.asStateFlow() }
|
||||
@ -32,7 +33,7 @@ class Consentium(
|
||||
suspend fun fetchConsents() {
|
||||
_fetchConsentState.value = FetchConsentiumState.Loading
|
||||
try {
|
||||
when (val consentResponse = consentiumRepository.getConsents(applicationId)) {
|
||||
when (val consentResponse = consentiumRepository.getConsents(apiKey)) {
|
||||
ConsentiumRepositoryGetResponse.Error -> _fetchConsentState.value = FetchConsentiumState.Error
|
||||
|
||||
is ConsentiumRepositoryGetResponse.GetConsentsSuccess -> {
|
||||
@ -54,7 +55,7 @@ class Consentium(
|
||||
) {
|
||||
_saveConsentState.emit(SetConsentiumState.Loading)
|
||||
try {
|
||||
when (consentiumRepository.setConsents(applicationId, consent)) {
|
||||
when (consentiumRepository.setConsents(apiKey, consent)) {
|
||||
ConsentiumRepositorySetResponse.Error -> {
|
||||
_saveConsentState.emit(SetConsentiumState.Error)
|
||||
}
|
||||
|
@ -11,12 +11,12 @@ import retrofit2.http.POST
|
||||
|
||||
internal interface ConsentiumApi {
|
||||
|
||||
@GET("/consents")
|
||||
@GET("consents")
|
||||
suspend fun getConsents(
|
||||
@Header("Authorization") token: String,
|
||||
): Response<GetConsent.GetConsentPayloadDTO>
|
||||
|
||||
@POST("/consents")
|
||||
@POST("consents")
|
||||
suspend fun setConsents(
|
||||
@Header("Authorization") token: String,
|
||||
@Body patchConsent: PatchConsent.PatchConsentPayloadDTO,
|
||||
|
@ -7,7 +7,7 @@ internal sealed interface GetConsent {
|
||||
|
||||
@Serializable
|
||||
data class GetConsentPayloadDTO(
|
||||
@SerialName("id") val id: String,
|
||||
@SerialName("id") val id: String? = null,
|
||||
@SerialName("installationId") val installationId: String,
|
||||
@SerialName("state") val state: ConsentStateDTO? = null,
|
||||
@SerialName("acceptedDate") val acceptedData: Long? = null,
|
||||
|
@ -16,10 +16,11 @@ internal class ConsentiumRepository @Inject constructor(
|
||||
private val getAuthTokenUseCase: GetAuthTokenUseCase,
|
||||
) {
|
||||
|
||||
suspend fun getConsents(applicationId: String): ConsentiumRepositoryGetResponse {
|
||||
val authToken = getAuthTokenUseCase(applicationId)
|
||||
val consentsResponse = consentiumApi.getConsents(authToken)
|
||||
suspend fun getConsents(apiKey: String): ConsentiumRepositoryGetResponse {
|
||||
|
||||
return try {
|
||||
val authToken = getAuthTokenUseCase(apiKey)
|
||||
val consentsResponse = consentiumApi.getConsents(authToken)
|
||||
val consentsBody = if (consentsResponse.isSuccessful) {
|
||||
consentsResponse.body() ?: throw Exception()
|
||||
} else {
|
||||
|
@ -5,7 +5,7 @@ import kotlin.io.encoding.Base64
|
||||
import kotlin.io.encoding.ExperimentalEncodingApi
|
||||
|
||||
interface GetAuthTokenUseCase {
|
||||
suspend operator fun invoke(applicationId: String): String
|
||||
suspend operator fun invoke(apiKey: String): String
|
||||
}
|
||||
|
||||
class GetAuthTokenUseCaseImpl @Inject internal constructor(
|
||||
@ -13,11 +13,11 @@ class GetAuthTokenUseCaseImpl @Inject internal constructor(
|
||||
) : GetAuthTokenUseCase {
|
||||
|
||||
@OptIn(ExperimentalEncodingApi::class)
|
||||
override suspend operator fun invoke(applicationId: String): String {
|
||||
override suspend operator fun invoke(apiKey: String): String {
|
||||
val uniqueInstallationId = getConsentiumUniqueInstallationIdUseCase()
|
||||
val clearToken = "$applicationId.$uniqueInstallationId"
|
||||
val clearToken = "$apiKey.$uniqueInstallationId"
|
||||
val cipheredToken = Base64.Default.encode(clearToken.toByteArray())
|
||||
return "Bearer $cipheredToken"
|
||||
return "Basic $cipheredToken"
|
||||
}
|
||||
|
||||
}
|
||||
|
4
consentium/src/prod/res/values/strings.xml
Normal file
4
consentium/src/prod/res/values/strings.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="backend_url" translatable="false" tools:ignore="UnusedResources">https://consentium-api.openium.fr/api/v1/app/</string>
|
||||
</resources>
|
Loading…
x
Reference in New Issue
Block a user