fix(CON-286) : Fix les transitions sur la navigation

This commit is contained in:
Louis Legrand 2025-02-20 10:38:28 +01:00
parent 4276adaf22
commit ed2d0ddb43
3 changed files with 103 additions and 15 deletions

View File

@ -1,3 +1,5 @@
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideIn
import androidx.compose.animation.slideOut
@ -32,27 +34,62 @@ import fr.openium.consentium_ui.ui.model.ConsentiumPageUI
private const val NAV_ANIMATION_TIME = 500
private val SLIDE_IN_FROM_RIGHT_ENTER_TRANSITION = slideIn(
animationSpec = tween(NAV_ANIMATION_TIME),
initialOffset = { fullSize -> IntOffset(x = fullSize.height, y = 0) }
)
private val SLIDE_IN_FROM_LEFT_ENTER_TRANSITION = slideIn(
animationSpec = tween(NAV_ANIMATION_TIME),
initialOffset = { fullSize -> IntOffset(x = -fullSize.height, y = 0) }
)
private val SLIDE_OUT_TO_LEFT_EXIT_TRANSITION = slideOut(
animationSpec = tween(NAV_ANIMATION_TIME),
targetOffset = { fullSize -> IntOffset(x = -fullSize.height, y = 0) }
)
private val SLIDE_OUT_TO_RIGHT_EXIT_TRANSITION = slideOut(
animationSpec = tween(NAV_ANIMATION_TIME),
targetOffset = { fullSize -> IntOffset(x = fullSize.height, y = 0) }
)
private infix fun String?.ifIn(destinations: List<Destination>): Boolean {
return this in destinations.map { it::class.qualifiedName }
}
private infix fun Boolean.thenTransitionWith(transition: EnterTransition): EnterTransition? {
return if (this) transition else null
}
private infix fun EnterTransition?.elseTransitionWith(transition: EnterTransition): EnterTransition {
return this ?: transition
}
private infix fun Boolean.thenTransitionWith(transition: ExitTransition): ExitTransition? {
return if (this) transition else null
}
private infix fun ExitTransition?.elseTransitionWith(transition: ExitTransition): ExitTransition {
return this ?: transition
}
@Composable
fun DemoNavGraph(navHostController: NavHostController) {
NavHost(
navController = navHostController,
startDestination = Destination.Splash,
enterTransition = {
slideIn(
animationSpec = tween(NAV_ANIMATION_TIME),
initialOffset = { fullSize -> IntOffset(x = fullSize.height, y = 0) }
)
},
exitTransition = {
slideOut(
animationSpec = tween(NAV_ANIMATION_TIME),
targetOffset = { fullSize -> IntOffset(x = -fullSize.height, y = 0) }
)
},
) {
composable<Destination.Splash> {
composable<Destination.Splash>(
enterTransition = {
SLIDE_IN_FROM_RIGHT_ENTER_TRANSITION
},
exitTransition = {
SLIDE_OUT_TO_LEFT_EXIT_TRANSITION
}
) {
SplashScreen(
navigateToMain = {
navHostController.navigate(Destination.Main) {
@ -67,7 +104,18 @@ fun DemoNavGraph(navHostController: NavHostController) {
)
}
composable<Destination.Main> {
composable<Destination.Main>(
enterTransition = {
initialState.destination.route ifIn listOf(
Destination.Splash
) thenTransitionWith SLIDE_IN_FROM_RIGHT_ENTER_TRANSITION elseTransitionWith SLIDE_IN_FROM_LEFT_ENTER_TRANSITION
},
exitTransition = {
targetState.destination.route ifIn listOf(
Destination.Splash
) thenTransitionWith SLIDE_OUT_TO_RIGHT_EXIT_TRANSITION elseTransitionWith SLIDE_OUT_TO_LEFT_EXIT_TRANSITION
}
) {
MainScreen(
onGoToConsentMaster = {
navHostController.navigate(Destination.Consent(ConsentiumPageUI.GENERAL_CONSENT))
@ -78,7 +126,20 @@ fun DemoNavGraph(navHostController: NavHostController) {
)
}
composable<Destination.Consent> { backStackEntry ->
composable<Destination.Consent>(
enterTransition = {
initialState.destination.route ifIn listOf(
Destination.Splash,
Destination.Main,
) thenTransitionWith SLIDE_IN_FROM_RIGHT_ENTER_TRANSITION elseTransitionWith SLIDE_IN_FROM_LEFT_ENTER_TRANSITION
},
exitTransition = {
targetState.destination.route ifIn listOf(
Destination.Splash,
Destination.Main,
) thenTransitionWith SLIDE_OUT_TO_RIGHT_EXIT_TRANSITION elseTransitionWith SLIDE_OUT_TO_LEFT_EXIT_TRANSITION
}
) { backStackEntry ->
val consent = backStackEntry.toRoute<Destination.Consent>()
val appId = stringResource(R.string.app_id)

View File

@ -18,6 +18,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import fr.openium.consentium.R
import fr.openium.consentium.api.Consentium
import fr.openium.consentium.api.checkPurposeState
import fr.openium.consentium.api.state.FetchConsentiumState
@Composable
@ -51,6 +52,22 @@ fun SplashScreen(
is FetchConsentiumState.Valid -> {
// The tracking services should be initialized here
val consents = consentState.purposes
consents.checkPurposeState("analytics") { consentState ->
// Initialize analytics
}
consents.checkPurposeState("ads") { consentState ->
// Initialize ads
}
consents.checkPurposeState("matomo") { consentState ->
// Initialize push
}
// Navigate on completion
navigateToMain()
}
}

View File

@ -3,7 +3,9 @@ package fr.openium.consentium.api
import android.content.Context
import dagger.hilt.android.EntryPointAccessors
import fr.openium.consentium.api.model.ConsentState
import fr.openium.consentium.api.model.Purpose
import fr.openium.consentium.api.model.PurposeChoice
import fr.openium.consentium.api.model.PurposeStatus
import fr.openium.consentium.api.state.FetchConsentiumState
import fr.openium.consentium.api.state.SetConsentiumState
import fr.openium.consentium.domain.di.RepositoryEntryPoint
@ -68,4 +70,12 @@ class Consentium(
_saveConsentState.emit(SetConsentiumState.Error)
}
}
}
fun List<Purpose>.checkPurposeState(purposeId: String, onPurposeState: (PurposeStatus) -> Unit) {
onPurposeState(find { it.identifier == purposeId }?.choice ?: PurposeStatus.REJECTED)
}
fun List<Purpose>.checkPurposeState(purposeId: String): PurposeStatus {
return find { it.identifier == purposeId }?.choice ?: PurposeStatus.REJECTED
}