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.core.tween
import androidx.compose.animation.slideIn import androidx.compose.animation.slideIn
import androidx.compose.animation.slideOut 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 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 @Composable
fun DemoNavGraph(navHostController: NavHostController) { fun DemoNavGraph(navHostController: NavHostController) {
NavHost( NavHost(
navController = navHostController, navController = navHostController,
startDestination = Destination.Splash, 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( SplashScreen(
navigateToMain = { navigateToMain = {
navHostController.navigate(Destination.Main) { 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( MainScreen(
onGoToConsentMaster = { onGoToConsentMaster = {
navHostController.navigate(Destination.Consent(ConsentiumPageUI.GENERAL_CONSENT)) 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 consent = backStackEntry.toRoute<Destination.Consent>()
val appId = stringResource(R.string.app_id) 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 androidx.compose.ui.unit.dp
import fr.openium.consentium.R import fr.openium.consentium.R
import fr.openium.consentium.api.Consentium import fr.openium.consentium.api.Consentium
import fr.openium.consentium.api.checkPurposeState
import fr.openium.consentium.api.state.FetchConsentiumState import fr.openium.consentium.api.state.FetchConsentiumState
@Composable @Composable
@ -51,6 +52,22 @@ fun SplashScreen(
is FetchConsentiumState.Valid -> { is FetchConsentiumState.Valid -> {
// The tracking services should be initialized here // 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() navigateToMain()
} }
} }

View File

@ -3,7 +3,9 @@ package fr.openium.consentium.api
import android.content.Context import android.content.Context
import dagger.hilt.android.EntryPointAccessors import dagger.hilt.android.EntryPointAccessors
import fr.openium.consentium.api.model.ConsentState 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.PurposeChoice
import fr.openium.consentium.api.model.PurposeStatus
import fr.openium.consentium.api.state.FetchConsentiumState import fr.openium.consentium.api.state.FetchConsentiumState
import fr.openium.consentium.api.state.SetConsentiumState import fr.openium.consentium.api.state.SetConsentiumState
import fr.openium.consentium.domain.di.RepositoryEntryPoint import fr.openium.consentium.domain.di.RepositoryEntryPoint
@ -69,3 +71,11 @@ class Consentium(
} }
} }
} }
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
}