diff --git a/feature/navigation/drawer/dropdown/src/debug/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/account/AccountViewPreview.kt b/feature/navigation/drawer/dropdown/src/debug/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/account/AccountViewPreview.kt index 10780abdf4d..82fd2b27d67 100644 --- a/feature/navigation/drawer/dropdown/src/debug/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/account/AccountViewPreview.kt +++ b/feature/navigation/drawer/dropdown/src/debug/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/account/AccountViewPreview.kt @@ -14,6 +14,7 @@ internal fun AccountViewPreview() { onClick = {}, onAvatarClick = {}, showAccountSelection = true, + isShowAnimations = true, ) } } @@ -27,6 +28,7 @@ internal fun AccountViewWithoutAccountPreview() { onClick = {}, onAvatarClick = {}, showAccountSelection = false, + isShowAnimations = true, ) } } diff --git a/feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/DrawerContent.kt b/feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/DrawerContent.kt index ca1624baa65..8ba14dc52e6 100644 --- a/feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/DrawerContent.kt +++ b/feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/DrawerContent.kt @@ -1,6 +1,10 @@ package net.thunderbird.feature.navigation.drawer.dropdown.ui import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.AnimatedContentTransitionScope +import androidx.compose.animation.ContentTransform +import androidx.compose.animation.core.FastOutSlowInEasing +import androidx.compose.animation.core.snap import androidx.compose.animation.core.tween import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideOutVertically @@ -14,7 +18,9 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.IntOffset +import android.provider.Settings import app.k9mail.core.ui.compose.designsystem.atom.DividerHorizontal import app.k9mail.core.ui.compose.designsystem.atom.Surface import app.k9mail.core.ui.compose.theme2.MainTheme @@ -31,7 +37,34 @@ import net.thunderbird.feature.navigation.drawer.dropdown.ui.folder.FolderList import net.thunderbird.feature.navigation.drawer.dropdown.ui.setting.AccountSettingList import net.thunderbird.feature.navigation.drawer.dropdown.ui.setting.FolderSettingList -private const val ANIMATION_DURATION_MS = 200 +private const val ANIMATION_DURATION_MS = 300 + +@Composable +private fun areSystemAnimationsEnabled(): Boolean { + return Settings.Global.getFloat( + LocalContext.current.contentResolver, + Settings.Global.ANIMATOR_DURATION_SCALE, + 1f, + ) != 0f +} + +private fun accountSelectorTransitionSpec( + areAnimationsEnabled: Boolean, +): AnimatedContentTransitionScope.() -> ContentTransform = { + if (areAnimationsEnabled) { + val animationSpec = tween(durationMillis = ANIMATION_DURATION_MS, easing = FastOutSlowInEasing) + if (targetState) { + slideInVertically(animationSpec = animationSpec) { -it } togetherWith + slideOutVertically(animationSpec = animationSpec) { it } + } else { + slideInVertically(animationSpec = animationSpec) { it } togetherWith + slideOutVertically(animationSpec = animationSpec) { -it } + } + } else { + slideInVertically(animationSpec = snap()) { 0 } togetherWith + slideOutVertically(animationSpec = snap()) { 0 } + } +} @Composable internal fun DrawerContent( @@ -40,6 +73,7 @@ internal fun DrawerContent( modifier: Modifier = Modifier, ) { val additionalWidth = getAdditionalWidth() + val areAnimationsEnabled = areSystemAnimationsEnabled() Surface( modifier = modifier @@ -59,6 +93,7 @@ internal fun DrawerContent( onClick = { onEvent(Event.OnAccountSelectorClick) }, onAvatarClick = { onEvent(Event.OnAccountViewClick(selectedAccount)) }, showAccountSelection = state.showAccountSelection, + isShowAnimations = areAnimationsEnabled, ) DividerHorizontal() @@ -66,16 +101,7 @@ internal fun DrawerContent( AnimatedContent( targetState = state.showAccountSelection, label = "AccountSelectorVisibility", - transitionSpec = { - val animationSpec = tween(durationMillis = ANIMATION_DURATION_MS) - if (targetState) { - slideInVertically(animationSpec = animationSpec) { -it } togetherWith - slideOutVertically(animationSpec = animationSpec) { it } - } else { - slideInVertically(animationSpec = animationSpec) { it } togetherWith - slideOutVertically(animationSpec = animationSpec) { -it } - } - }, + transitionSpec = accountSelectorTransitionSpec(areAnimationsEnabled), ) { targetState -> if (targetState) { AccountContent( diff --git a/feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/account/AccountView.kt b/feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/account/AccountView.kt index cb1942167d9..f6b25e32166 100644 --- a/feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/account/AccountView.kt +++ b/feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/account/AccountView.kt @@ -1,6 +1,7 @@ package net.thunderbird.feature.navigation.drawer.dropdown.ui.account import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.core.snap import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.slideInHorizontally @@ -44,6 +45,7 @@ internal fun AccountView( onClick: () -> Unit, onAvatarClick: () -> Unit, showAccountSelection: Boolean, + isShowAnimations: Boolean, modifier: Modifier = Modifier, ) { AccountLayout( @@ -56,11 +58,13 @@ internal fun AccountView( AccountSelectedView( account = account, onAvatarClick = onAvatarClick, + isShowAnimations = isShowAnimations, ) } AnimatedExpandIcon( isExpanded = showAccountSelection, + isShowAnimations = isShowAnimations, modifier = Modifier.padding(end = MainTheme.spacings.double), tint = MainTheme.colors.onSurfaceVariant, ) @@ -71,12 +75,18 @@ internal fun AccountView( private fun RowScope.AccountSelectedView( account: DisplayAccount, onAvatarClick: () -> Unit, + isShowAnimations: Boolean, ) { AnimatedContent( targetState = account, transitionSpec = { - (slideInHorizontally { it } + fadeIn()) togetherWith - (slideOutHorizontally { -it } + fadeOut()) + if (isShowAnimations) { + (slideInHorizontally { it } + fadeIn()) togetherWith + (slideOutHorizontally { -it } + fadeOut()) + } else { + (slideInHorizontally(animationSpec = snap()) { 0 } + fadeIn(animationSpec = snap())) togetherWith + (slideOutHorizontally(animationSpec = snap()) { 0 } + fadeOut(animationSpec = snap())) + } }, label = "AccountSelectedContent", contentKey = { it.id }, diff --git a/feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/common/AnimatedExpandIcon.kt b/feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/common/AnimatedExpandIcon.kt index 996999b9376..1c61d119634 100644 --- a/feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/common/AnimatedExpandIcon.kt +++ b/feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/common/AnimatedExpandIcon.kt @@ -1,6 +1,8 @@ package net.thunderbird.feature.navigation.drawer.dropdown.ui.common import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.animation.core.snap +import androidx.compose.animation.core.spring import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier @@ -13,10 +15,12 @@ import net.thunderbird.core.ui.compose.designsystem.atom.icon.Icons internal fun AnimatedExpandIcon( isExpanded: Boolean, modifier: Modifier = Modifier, + isShowAnimations: Boolean = true, tint: Color? = null, ) { val rotationAngle by animateFloatAsState( targetValue = if (isExpanded) 180f else 0f, + animationSpec = if (isShowAnimations) spring() else snap(), label = "rotationAngle", )