feat(CON-171) : Summary consent screen

feat(CON-172) : Detail consent screen
feat(-) : Send consent to BO to save them
This commit is contained in:
2024-12-20 09:51:57 +01:00
committed by Louis Legrand
parent d406cc703f
commit 86a7020c2b
69 changed files with 1788 additions and 255 deletions

View File

@ -6,10 +6,9 @@ plugins {
alias(libs.plugins.ksp)
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.hilt)
alias(libs.plugins.serialization)
alias(libs.plugins.kotlin.compose)
}
// Keystore
@ -106,6 +105,8 @@ dependencies {
implementation(libs.hilt.android)
ksp(libs.hilt.compiler)
implementation(libs.hilt.navigation.compose)
// Libs analytics
implementation(libs.matomo)
implementation(libs.clarity)
implementation(libs.ga4)

View File

@ -1,6 +1,6 @@
package fr.openium.consentium
import fr.openium.consentium.ui.navigation.DemoNavGraph
import DemoNavGraph
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
@ -24,7 +24,7 @@ class MainActivity : ComponentActivity() {
val navHostController = rememberNavController()
ConsentiumTheme {
Scaffold( modifier = Modifier.fillMaxSize() ) { paddingValues ->
Scaffold(modifier = Modifier.fillMaxSize()) { paddingValues ->
Box(
modifier = Modifier
.fillMaxSize()

View File

@ -1,17 +1,32 @@
package fr.openium.consentium.ui.navigation
import Destination
import androidx.compose.animation.core.tween
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.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.api.Consentium
import fr.openium.consentium.ui.screens.main.MainScreen
import fr.openium.consentium.ui.screens.splash.SplashScreen
import fr.openium.consentium.ui.theme.Error
import fr.openium.consentium.ui.theme.OnPrimary
import fr.openium.consentium.ui.theme.OnSecondary
import fr.openium.consentium.ui.theme.OnSurface
import fr.openium.consentium.ui.theme.OnSurfaceVariant
import fr.openium.consentium.ui.theme.Primary
import fr.openium.consentium.ui.theme.Secondary
import fr.openium.consentium.ui.theme.Success
import fr.openium.consentium.ui.theme.SurfaceHigh
import fr.openium.consentium.ui.theme.SurfaceHighest
import fr.openium.consentium.ui.theme.SurfaceMiddle
import fr.openium.consentium.ui.theme.Tertiary
import fr.openium.consentium_ui.ui.components.ConsentiumComponent
import fr.openium.consentium_ui.ui.components.style.ConsentiumDefaults
import fr.openium.consentium_ui.ui.model.ConsentiumPageUI
private const val NAV_ANIMATION_TIME = 500
@ -43,23 +58,56 @@ fun DemoNavGraph(navHostController: NavHostController) {
saveState = true
}
}
},
navigateToConsent = {
navHostController.navigate(Destination.Consent(ConsentiumPageUI.GENERAL_CONSENT))
}
)
}
composable<Destination.Main> {
MainScreen(
onGoToConsentDetail = {
navHostController.navigate(Destination.Consent)
},
onGoToConsentMaster = {
navHostController.navigate(Destination.Consent)
}
navHostController.navigate(Destination.Consent(ConsentiumPageUI.GENERAL_CONSENT))
},
onGoToConsentDetail = {
navHostController.navigate(Destination.Consent(ConsentiumPageUI.DETAILS_CONSENT))
},
)
}
composable<Destination.Consent> {
// TODO
composable<Destination.Consent> { backStackEntry ->
val consent = backStackEntry.toRoute<Destination.Consent>()
val context = LocalContext.current
ConsentiumComponent(
defaultLandingPage = consent.landingPage,
onQuitConsent = {
navHostController.navigate(Destination.Main) {
popUpTo(navHostController.graph.findStartDestination().id) {
saveState = true
}
}
},
consentium = Consentium(
context = context,
applicationId = "ApplicationId",
),
colors = ConsentiumDefaults.colors(
primary = Primary,
onPrimary = OnPrimary,
secondary = Secondary,
onSecondary = OnSecondary,
tertiary = Tertiary,
onSurfaceVariant = OnSurfaceVariant,
onSurface = OnSurface,
error = Error,
surfaceHighest = SurfaceHighest,
surfaceHigh = SurfaceHigh,
surfaceMiddle = SurfaceMiddle,
success = Success,
)
)
}
}
}

View File

@ -1,3 +1,4 @@
import fr.openium.consentium_ui.ui.model.ConsentiumPageUI
import kotlinx.serialization.Serializable
@ -10,6 +11,8 @@ sealed interface Destination {
data object Main : Destination
@Serializable
data object Consent : Destination
data class Consent(
val landingPage: ConsentiumPageUI
): Destination
}

View File

@ -1,10 +0,0 @@
package fr.openium.consentium.ui.screens.consent
import androidx.compose.runtime.Composable
@Composable
fun ConsentScreen() {
}

View File

@ -43,7 +43,5 @@ fun MainScreen(
text = "Go to Consent Detail"
)
}
}
}

View File

@ -10,36 +10,51 @@ import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import fr.openium.consentium.api.Consentium
import fr.openium.consentium.api.state.FetchConsentiumState
@Composable
fun SplashScreen(
navigateToMain: () -> Unit,
viewModel: SplashScreenViewModel = hiltViewModel(),
navigateToConsent: () -> Unit,
) {
// State
val currentState by viewModel.state.collectAsState()
// Property
val context = LocalContext.current
val consentium = remember { Consentium(context = context, applicationId = "DemoApplicationId") }
// Effect
LaunchedEffect(Unit) {
viewModel.initMain()
}
consentium.fetchConsentState.collect { consentState ->
when (consentState) {
FetchConsentiumState.Idle,
FetchConsentiumState.Loading -> {}
LaunchedEffect(currentState) {
when (val state = currentState) {
is SplashScreenViewModel.State.Loaded -> {
if (state.isSplashEnded) {
FetchConsentiumState.Error -> {
// Handle error
consentium.fetchConsents()
}
is FetchConsentiumState.Invalid -> {
navigateToConsent()
}
is FetchConsentiumState.Valid -> {
// The tracking services should be initialized here
navigateToMain()
}
}
}
}
LaunchedEffect(Unit) {
consentium.fetchConsents()
}
// View
Column(
modifier = Modifier.fillMaxSize(),
@ -47,7 +62,7 @@ fun SplashScreen(
verticalArrangement = Arrangement.Center
) {
Text("Splash Screen")
Text("Splash Screen") // TODO
Spacer(modifier = Modifier.height(14.dp))

View File

@ -1,30 +0,0 @@
package fr.openium.consentium.ui.screens.splash
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class SplashScreenViewModel @Inject constructor(
) : ViewModel() {
private val _state = MutableStateFlow<State>(State.Loaded(false))
val state: StateFlow<State> = _state
fun initMain() {
viewModelScope.launch {
delay(1500L)
_state.value = State.Loaded(true)
}
}
sealed interface State {
data class Loaded(val isSplashEnded: Boolean) : State
}
}

View File

@ -2,10 +2,21 @@ package fr.openium.consentium.ui.theme
import androidx.compose.ui.graphics.Color
val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)
val Primary = Color(0xFF70ACDC)
val OnPrimary = Color(0XFFFFFFFF)
val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260)
val Secondary = Color(0xFFF29413)
val OnSecondary = Color(0xFFFFFFFF)
val Tertiary = Color(0xFF3470A0)
val OnSurfaceVariant = Color(0xFF3470A0)
val OnSurface = Color(0xFF163752)
val Error = Color(0xFF3470A0)
val SurfaceHighest = Color(0xFFFFFFFF)
val SurfaceHigh = Color(0xFFF2F8FC)
val SurfaceMiddle = Color(0xFFD6E6F5)
val Success = Color(0xFF479B3F)

View File

@ -1,39 +1,29 @@
package fr.openium.consentium.ui.theme
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
private val DarkColorScheme = darkColorScheme(
primary = Purple80,
secondary = PurpleGrey80,
tertiary = Pink80
primary = Primary,
secondary = Secondary,
tertiary = Tertiary
)
private val LightColorScheme = lightColorScheme(
primary = Purple40,
secondary = PurpleGrey40,
tertiary = Pink40
primary = Primary,
secondary = Secondary,
tertiary = Tertiary
)
@Composable
fun ConsentiumTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = true,
content: @Composable () -> Unit,
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColorScheme
else -> LightColorScheme
}