From af91841857a7b4142f7eaeeeba7e14e2ee5f46e4 Mon Sep 17 00:00:00 2001 From: Louis Legrand Date: Tue, 11 Feb 2025 17:00:53 +0100 Subject: [PATCH] feat(CON-265) : Aligner les flux de l'api d'UI avec les nouveaux dev back --- .../consentium/ui/navigation/DemoNavGraph.kt | 8 +- .../ui/screens/splash/SplashScreen.kt | 5 +- app/src/main/res/values/strings.xml | 3 +- consentium-ui/src/main/AndroidManifest.xml | 1 + .../data/remote/ConsentiumUIApi.kt | 8 +- .../data/remote/mock/ConsentiumUIMock.kt | 108 ++---------------- .../data/remote/model/GetConsentConfigDTO.kt | 8 +- .../model/MainConsentTextTranslationDTO.kt | 3 +- .../data/remote/model/PurposeDTO.kt | 8 +- .../data/remote/model/PurposeStatusDTO.kt | 10 +- .../domain/adapter/PurposeDataAdapter.kt | 4 +- .../adapter/PurposeStatusDataAdapter.kt | 4 +- .../domain/model/ContentConfigData.kt | 2 +- .../consentium_ui/domain/model/PurposeData.kt | 2 +- .../domain/model/PurposeStatusData.kt | 2 +- .../repository/ConsentiumUIRepository.kt | 13 ++- .../consentium_ui/ui/ConsentiumUIScreen.kt | 2 + .../consentium_ui/ui/ConsentiumUIViewModel.kt | 29 +++-- .../ui/adapter/DetailConsentUIAdapter.kt | 16 ++- .../ui/adapter/PurposeStatusUIAdapter.kt | 2 +- .../ui/adapter/PurposeUIAdapter.kt | 2 +- .../ui/components/ConsentiumUIComponent.kt | 5 +- .../components/ConsentiumUIErrorComponent.kt | 23 +++- .../ui/components/core/PurposeComponent.kt | 6 +- .../ui/model/GeneralConsentUI.kt | 2 +- .../consentium_ui/ui/model/PurposeStatusUI.kt | 2 +- .../consentium_ui/ui/model/PurposeUI.kt | 2 +- consentium-ui/src/main/res/values/strings.xml | 2 + consentium/src/dev/res/values/strings.xml | 4 +- consentium/src/main/AndroidManifest.xml | 2 + .../fr/openium/consentium/api/Consentium.kt | 7 +- .../consentium/data/remote/ConsentiumApi.kt | 4 +- .../data/remote/model/GetConsentPayloadDTO.kt | 2 +- .../domain/repository/ConsentiumRepository.kt | 7 +- .../domain/useCase/GetAuthTokenUseCase.kt | 8 +- consentium/src/prod/res/values/strings.xml | 4 + 36 files changed, 144 insertions(+), 176 deletions(-) create mode 100644 consentium/src/prod/res/values/strings.xml diff --git a/app/src/main/java/fr/openium/consentium/ui/navigation/DemoNavGraph.kt b/app/src/main/java/fr/openium/consentium/ui/navigation/DemoNavGraph.kt index 90dbdf0..8a85499 100644 --- a/app/src/main/java/fr/openium/consentium/ui/navigation/DemoNavGraph.kt +++ b/app/src/main/java/fr/openium/consentium/ui/navigation/DemoNavGraph.kt @@ -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 { backStackEntry -> val consent = backStackEntry.toRoute() + 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, diff --git a/app/src/main/java/fr/openium/consentium/ui/screens/splash/SplashScreen.kt b/app/src/main/java/fr/openium/consentium/ui/screens/splash/SplashScreen.kt index 6bd44ef..db200c0 100644 --- a/app/src/main/java/fr/openium/consentium/ui/screens/splash/SplashScreen.kt +++ b/app/src/main/java/fr/openium/consentium/ui/screens/splash/SplashScreen.kt @@ -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) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6e676d2..151563c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,4 +1,5 @@ Consentium - 01938ce4-331a-7592-9e90-f09201ff4f36 + 01938ce4-331a-7592-9e90-f09201ff4f36 + c452a27f-2e90-427d-be82-2f631c31dd09 \ No newline at end of file diff --git a/consentium-ui/src/main/AndroidManifest.xml b/consentium-ui/src/main/AndroidManifest.xml index a880029..294dbaa 100644 --- a/consentium-ui/src/main/AndroidManifest.xml +++ b/consentium-ui/src/main/AndroidManifest.xml @@ -1,4 +1,5 @@ + \ No newline at end of file diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/ConsentiumUIApi.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/ConsentiumUIApi.kt index c97bf2d..4152ec2 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/ConsentiumUIApi.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/ConsentiumUIApi.kt @@ -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 } \ No newline at end of file diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/mock/ConsentiumUIMock.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/mock/ConsentiumUIMock.kt index 1c79025..f238931 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/mock/ConsentiumUIMock.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/mock/ConsentiumUIMock.kt @@ -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 = "

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

\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 = "

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).

" - ) - ) - ), - VendorDTO( - id = "vendors-matomo", - order = 1, - isAccepted = true, - isRequired = false, - translations = listOf( - VendorTranslationDTO( - id = "UUID", - language = "fr", - text = "

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).

" - ) - ) - ) - ) ), 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 = "

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.

" - ) - ) - ) - ) ), 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 = "

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.

" - ) - ) - ) - ) ), 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 = "

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.

" - ) - ) - ) - ) ), 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 = "

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.

" - ) - ) - ) - ) ) ) ) override suspend fun getConsentConfig( - applicationID: String, - installationID: String, + token: String, + applicationId: String, ): Response { return Response.success(consents) } diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/GetConsentConfigDTO.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/GetConsentConfigDTO.kt index 118c107..6d36ae5 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/GetConsentConfigDTO.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/GetConsentConfigDTO.kt @@ -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, + @SerialName("icon") val icon: String? = null, + @SerialName("consentPageUrl") val consentPageUrl: String, + @SerialName("translations") val consentMainTextTranslation: List, @SerialName("purposes") val purposes: List, ) \ No newline at end of file diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/MainConsentTextTranslationDTO.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/MainConsentTextTranslationDTO.kt index 69b52bf..b8819ea 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/MainConsentTextTranslationDTO.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/MainConsentTextTranslationDTO.kt @@ -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, + ) \ No newline at end of file diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/PurposeDTO.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/PurposeDTO.kt index 4281a71..07a9588 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/PurposeDTO.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/PurposeDTO.kt @@ -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, - @SerialName("vendors") val vendors: List, + @SerialName("identifier") val id: String, + ) diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/PurposeStatusDTO.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/PurposeStatusDTO.kt index 9476710..422f8f5 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/PurposeStatusDTO.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/data/remote/model/PurposeStatusDTO.kt @@ -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, } \ No newline at end of file diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/adapter/PurposeDataAdapter.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/adapter/PurposeDataAdapter.kt index e48e322..fdf7ba4 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/adapter/PurposeDataAdapter.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/adapter/PurposeDataAdapter.kt @@ -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(), ) diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/adapter/PurposeStatusDataAdapter.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/adapter/PurposeStatusDataAdapter.kt index d688a82..2d5fa8b 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/adapter/PurposeStatusDataAdapter.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/adapter/PurposeStatusDataAdapter.kt @@ -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 } } \ No newline at end of file diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/model/ContentConfigData.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/model/ContentConfigData.kt index e0d6a9c..8d64f7f 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/model/ContentConfigData.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/model/ContentConfigData.kt @@ -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, val purposes: List ) diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/model/PurposeData.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/model/PurposeData.kt index 4f751aa..c2785df 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/model/PurposeData.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/model/PurposeData.kt @@ -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, val vendors: List, ) diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/model/PurposeStatusData.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/model/PurposeStatusData.kt index 059a684..d2b916f 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/model/PurposeStatusData.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/model/PurposeStatusData.kt @@ -3,5 +3,5 @@ package fr.openium.consentium_ui.domain.model internal enum class PurposeStatusData { ACCEPTED, REJECTED, - NOT_DEFINED, + PARTIAL, } \ No newline at end of file diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/repository/ConsentiumUIRepository.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/repository/ConsentiumUIRepository.kt index 49fa1a5..ff192a5 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/repository/ConsentiumUIRepository.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/domain/repository/ConsentiumUIRepository.kt @@ -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 { diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/ConsentiumUIScreen.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/ConsentiumUIScreen.kt index d842e1f..5064a8e 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/ConsentiumUIScreen.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/ConsentiumUIScreen.kt @@ -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 ) } diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/ConsentiumUIViewModel.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/ConsentiumUIViewModel.kt index cca69a1..2264ab4 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/ConsentiumUIViewModel.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/ConsentiumUIViewModel.kt @@ -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.Loading) val state: StateFlow 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( - generalConsentUI = consentUI.configData.toGeneralConsentUI(), - detailConsentUI = consentUI.configData.toDetailConsentUI(), - )) + _state.emit( + ConsentiumUIState.Loaded( + generalConsentUI = consentUI.configData.toGeneralConsentUI(), + detailConsentUI = consentUI.configData.toDetailConsentUI(), + ) + ) } is GetConfigTextForLanguageUseCaseResponse.DefaultLanguage -> { - _state.emit(ConsentiumUIState.Loaded( - generalConsentUI = consentUI.configData.toGeneralConsentUI(), - detailConsentUI = consentUI.configData.toDetailConsentUI(), - )) + _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)) } } diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/adapter/DetailConsentUIAdapter.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/adapter/DetailConsentUIAdapter.kt index 40af5fb..e0d5bd9 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/adapter/DetailConsentUIAdapter.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/adapter/DetailConsentUIAdapter.kt @@ -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 = purposes. } internal fun DetailConsentUI.toDeniedPurposeChoices(): List = purposes.map { - it.toPurposeChoice().copy(isAccepted = false) + it.toPurposeChoice().copy(choice = PurposeStatus.REJECTED) } internal fun DetailConsentUI.toAcceptedPurposeChoices(): List = 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 - ) \ No newline at end of file + ) + +internal fun PurposeStatusUI.toPurposeStatus(): PurposeStatus = + when (this) { + PurposeStatusUI.ACCEPTED -> PurposeStatus.ACCEPTED + PurposeStatusUI.REJECTED -> PurposeStatus.REJECTED + PurposeStatusUI.PARTIAL -> PurposeStatus.PARTIAL + } \ No newline at end of file diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/adapter/PurposeStatusUIAdapter.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/adapter/PurposeStatusUIAdapter.kt index b34c94e..4c60f59 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/adapter/PurposeStatusUIAdapter.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/adapter/PurposeStatusUIAdapter.kt @@ -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 } \ No newline at end of file diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/adapter/PurposeUIAdapter.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/adapter/PurposeUIAdapter.kt index 75b1aef..d9bf125 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/adapter/PurposeUIAdapter.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/adapter/PurposeUIAdapter.kt @@ -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(), diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/components/ConsentiumUIComponent.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/components/ConsentiumUIComponent.kt index 43535d7..051e27c 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/components/ConsentiumUIComponent.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/components/ConsentiumUIComponent.kt @@ -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) + } ) } } diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/components/ConsentiumUIErrorComponent.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/components/ConsentiumUIErrorComponent.kt index 4b18b74..037e39c 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/components/ConsentiumUIErrorComponent.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/components/ConsentiumUIErrorComponent.kt @@ -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, ) } } \ No newline at end of file diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/components/core/PurposeComponent.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/components/core/PurposeComponent.kt index 3e7aab4..4fca922 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/components/core/PurposeComponent.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/components/core/PurposeComponent.kt @@ -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(), diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/model/GeneralConsentUI.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/model/GeneralConsentUI.kt index 118b6cc..71a4bb8 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/model/GeneralConsentUI.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/model/GeneralConsentUI.kt @@ -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, ) \ No newline at end of file diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/model/PurposeStatusUI.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/model/PurposeStatusUI.kt index c0bf849..6323d89 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/model/PurposeStatusUI.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/model/PurposeStatusUI.kt @@ -3,5 +3,5 @@ package fr.openium.consentium_ui.ui.model internal enum class PurposeStatusUI { ACCEPTED, REJECTED, - NOT_DEFINED, + PARTIAL, } \ No newline at end of file diff --git a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/model/PurposeUI.kt b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/model/PurposeUI.kt index adbe3ac..0d9dd57 100644 --- a/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/model/PurposeUI.kt +++ b/consentium-ui/src/main/java/fr/openium/consentium_ui/ui/model/PurposeUI.kt @@ -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, diff --git a/consentium-ui/src/main/res/values/strings.xml b/consentium-ui/src/main/res/values/strings.xml index b495dd0..dd2a552 100644 --- a/consentium-ui/src/main/res/values/strings.xml +++ b/consentium-ui/src/main/res/values/strings.xml @@ -6,5 +6,7 @@ Paramétrer mes choix Enregistrer et fermer Requis + Réessayer Une erreur est survenue l\'or de la ssauvegarde de vos consentements. + Il y a eu une erreur lors du chargement de vos consentements \ No newline at end of file diff --git a/consentium/src/dev/res/values/strings.xml b/consentium/src/dev/res/values/strings.xml index c04ccc1..9cd1a46 100644 --- a/consentium/src/dev/res/values/strings.xml +++ b/consentium/src/dev/res/values/strings.xml @@ -1,4 +1,4 @@ - - https://consentium-api-dev.openium.fr/api/v1/app + + https://consentium-api-dev.openium.fr/api/v1/app/ \ No newline at end of file diff --git a/consentium/src/main/AndroidManifest.xml b/consentium/src/main/AndroidManifest.xml index a5918e6..16b8f6e 100644 --- a/consentium/src/main/AndroidManifest.xml +++ b/consentium/src/main/AndroidManifest.xml @@ -1,4 +1,6 @@ + + \ No newline at end of file diff --git a/consentium/src/main/java/fr/openium/consentium/api/Consentium.kt b/consentium/src/main/java/fr/openium/consentium/api/Consentium.kt index d8c4dc5..60e1bc8 100644 --- a/consentium/src/main/java/fr/openium/consentium/api/Consentium.kt +++ b/consentium/src/main/java/fr/openium/consentium/api/Consentium.kt @@ -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.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) } diff --git a/consentium/src/main/java/fr/openium/consentium/data/remote/ConsentiumApi.kt b/consentium/src/main/java/fr/openium/consentium/data/remote/ConsentiumApi.kt index 23a6bdd..b14fc61 100644 --- a/consentium/src/main/java/fr/openium/consentium/data/remote/ConsentiumApi.kt +++ b/consentium/src/main/java/fr/openium/consentium/data/remote/ConsentiumApi.kt @@ -11,12 +11,12 @@ import retrofit2.http.POST internal interface ConsentiumApi { - @GET("/consents") + @GET("consents") suspend fun getConsents( @Header("Authorization") token: String, ): Response - @POST("/consents") + @POST("consents") suspend fun setConsents( @Header("Authorization") token: String, @Body patchConsent: PatchConsent.PatchConsentPayloadDTO, diff --git a/consentium/src/main/java/fr/openium/consentium/data/remote/model/GetConsentPayloadDTO.kt b/consentium/src/main/java/fr/openium/consentium/data/remote/model/GetConsentPayloadDTO.kt index 53781f2..695da6e 100644 --- a/consentium/src/main/java/fr/openium/consentium/data/remote/model/GetConsentPayloadDTO.kt +++ b/consentium/src/main/java/fr/openium/consentium/data/remote/model/GetConsentPayloadDTO.kt @@ -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, diff --git a/consentium/src/main/java/fr/openium/consentium/domain/repository/ConsentiumRepository.kt b/consentium/src/main/java/fr/openium/consentium/domain/repository/ConsentiumRepository.kt index f4e1472..c5bcae8 100644 --- a/consentium/src/main/java/fr/openium/consentium/domain/repository/ConsentiumRepository.kt +++ b/consentium/src/main/java/fr/openium/consentium/domain/repository/ConsentiumRepository.kt @@ -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 { diff --git a/consentium/src/main/java/fr/openium/consentium/domain/useCase/GetAuthTokenUseCase.kt b/consentium/src/main/java/fr/openium/consentium/domain/useCase/GetAuthTokenUseCase.kt index e6a8301..495df48 100644 --- a/consentium/src/main/java/fr/openium/consentium/domain/useCase/GetAuthTokenUseCase.kt +++ b/consentium/src/main/java/fr/openium/consentium/domain/useCase/GetAuthTokenUseCase.kt @@ -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" } } diff --git a/consentium/src/prod/res/values/strings.xml b/consentium/src/prod/res/values/strings.xml new file mode 100644 index 0000000..ea16450 --- /dev/null +++ b/consentium/src/prod/res/values/strings.xml @@ -0,0 +1,4 @@ + + + https://consentium-api.openium.fr/api/v1/app/ + \ No newline at end of file