Skip to content

Commit

Permalink
Update transitions
Browse files Browse the repository at this point in the history
  • Loading branch information
Rawa committed Dec 6, 2023
1 parent e07edf0 commit 5e79902
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 49 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package net.mullvad.mullvadvpn.compose.transitions

import android.util.Log
import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.snap
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
Expand All @@ -18,25 +16,13 @@ object LoginTransition : DestinationStyle.Animated {

// TODO temporary hack until we have a proper solution.
// https://issuetracker.google.com/issues/309506799
override fun AnimatedContentTransitionScope<NavBackStackEntry>.exitTransition():
ExitTransition {
val transition =
when (this.targetState.destination()) {
is OutOfTimeDestination,
is WelcomeDestination,
is ConnectDestination -> {
Log.d("LoginTransition", "was slide anim!")
fadeOut()
}
else -> fadeOut(snap(400))
}

Log.d(
"LoginTransition",
"exitTransition: ${this.targetState.destination()}" + "transition: $transition"
)
return transition
}
override fun AnimatedContentTransitionScope<NavBackStackEntry>.exitTransition() =
when (this.targetState.destination()) {
is OutOfTimeDestination,
is WelcomeDestination,
is ConnectDestination -> fadeOut()
else -> fadeOut(snap(400))
}

override fun AnimatedContentTransitionScope<NavBackStackEntry>.popEnterTransition() = fadeIn()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
package net.mullvad.mullvadvpn.compose.transitions

import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.core.snap
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.animation.slideOutVertically
import androidx.navigation.NavBackStackEntry
import com.ramcosta.composedestinations.spec.DestinationStyle
import com.ramcosta.composedestinations.utils.destination
import net.mullvad.mullvadvpn.compose.destinations.NoDaemonScreenDestination

object SettingsTransition : DestinationStyle.Animated {
override fun AnimatedContentTransitionScope<NavBackStackEntry>.enterTransition() =
slideInVertically(initialOffsetY = { it })

override fun AnimatedContentTransitionScope<NavBackStackEntry>.exitTransition() =
slideOutHorizontally(targetOffsetX = { -it })
when (targetState.destination()) {
NoDaemonScreenDestination -> fadeOut(snap(400))
else -> slideOutHorizontally(targetOffsetX = { -it/3 })
}

override fun AnimatedContentTransitionScope<NavBackStackEntry>.popEnterTransition() =
slideInHorizontally(initialOffsetX = { -it })
when (initialState.destination()) {
NoDaemonScreenDestination -> fadeIn(snap(0))
else -> slideInHorizontally(initialOffsetX = { -it/3 })
}

override fun AnimatedContentTransitionScope<NavBackStackEntry>.popExitTransition() =
slideOutVertically(targetOffsetY = { it })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,56 @@
package net.mullvad.mullvadvpn.compose.transitions

import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.snap
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.animation.slideOutVertically
import androidx.navigation.NavBackStackEntry
import com.ramcosta.composedestinations.spec.DestinationStyle
import com.ramcosta.composedestinations.utils.destination
import net.mullvad.mullvadvpn.compose.destinations.NoDaemonScreenDestination

object SlideInFromBottomTransition : DestinationStyle.Animated {
override fun AnimatedContentTransitionScope<NavBackStackEntry>.enterTransition():
EnterTransition {
return slideInVertically(initialOffsetY = { it })
}
override fun AnimatedContentTransitionScope<NavBackStackEntry>.enterTransition() =
slideInVertically(initialOffsetY = { it })

override fun AnimatedContentTransitionScope<NavBackStackEntry>.popEnterTransition() = null

override fun AnimatedContentTransitionScope<NavBackStackEntry>.popExitTransition():
ExitTransition {
return slideOutVertically(targetOffsetY = { it })
}
override fun AnimatedContentTransitionScope<NavBackStackEntry>.exitTransition() =
when (targetState.destination()) {
NoDaemonScreenDestination -> fadeOut(snap(400))
else -> fadeOut()
}

override fun AnimatedContentTransitionScope<NavBackStackEntry>.popEnterTransition() =
when (initialState.destination()) {
NoDaemonScreenDestination -> fadeIn(snap(0))
else -> fadeIn()
}

override fun AnimatedContentTransitionScope<NavBackStackEntry>.popExitTransition() =
slideOutVertically(targetOffsetY = { it })
}

object SelectLocationTransition : DestinationStyle.Animated {
override fun AnimatedContentTransitionScope<NavBackStackEntry>.enterTransition():
EnterTransition {
return slideInVertically(initialOffsetY = { it })
}
override fun AnimatedContentTransitionScope<NavBackStackEntry>.enterTransition() =
slideInVertically(initialOffsetY = { it })

// TODO temporary hack until we have a proper solution.
// https://issuetracker.google.com/issues/309506799
override fun AnimatedContentTransitionScope<NavBackStackEntry>.exitTransition() =
fadeOut(snap(400))

override fun AnimatedContentTransitionScope<NavBackStackEntry>.popEnterTransition() = null

override fun AnimatedContentTransitionScope<NavBackStackEntry>.popExitTransition():
ExitTransition {
return slideOutVertically(targetOffsetY = { it })
}
when (targetState.destination()) {
NoDaemonScreenDestination -> fadeOut(snap(400))
else -> slideOutHorizontally { -it/3 }
}

override fun AnimatedContentTransitionScope<NavBackStackEntry>.popEnterTransition() =
when (initialState.destination()) {
NoDaemonScreenDestination -> fadeIn(snap(0))
else -> slideInHorizontally { -it/3 }
}

override fun AnimatedContentTransitionScope<NavBackStackEntry>.popExitTransition() =
slideOutVertically(targetOffsetY = { it })
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
package net.mullvad.mullvadvpn.compose.transitions

import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.core.snap
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.navigation.NavBackStackEntry
import com.ramcosta.composedestinations.spec.DestinationStyle
import com.ramcosta.composedestinations.utils.destination
import net.mullvad.mullvadvpn.compose.destinations.NoDaemonScreenDestination

object SlideInFromRightTransition : DestinationStyle.Animated {
override fun AnimatedContentTransitionScope<NavBackStackEntry>.enterTransition() =
slideInHorizontally(initialOffsetX = { it })

override fun AnimatedContentTransitionScope<NavBackStackEntry>.exitTransition() =
slideOutHorizontally(targetOffsetX = { -it })
when (targetState.destination()) {
NoDaemonScreenDestination -> fadeOut(snap(400))
else -> slideOutHorizontally(targetOffsetX = { -it/3 })
}

override fun AnimatedContentTransitionScope<NavBackStackEntry>.popEnterTransition() =
slideInHorizontally(initialOffsetX = { -it })
when (initialState.destination()) {
NoDaemonScreenDestination -> fadeIn(snap(0))
else -> slideInHorizontally(initialOffsetX = { -it/3 })
}

override fun AnimatedContentTransitionScope<NavBackStackEntry>.popExitTransition() =
slideOutHorizontally(targetOffsetX = { it })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ package net.mullvad.mullvadvpn.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.FlowPreview
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionState

class ServiceConnectionViewModel(serviceConnectionManager: ServiceConnectionManager) : ViewModel() {
@OptIn(FlowPreview::class)
val uiState =
serviceConnectionManager.connectionState
.map {
Expand All @@ -18,11 +22,24 @@ class ServiceConnectionViewModel(serviceConnectionManager: ServiceConnectionMana
ServiceConnectionState.Disconnected -> ServiceState.Disconnected
}
}
// We debounce any disconnected state to let the UI have some time to connect after a
// onPaused/onResumed event.
.debounce {
when (it) {
is ServiceState.Connected -> 0.seconds
is ServiceState.Disconnected -> SERVICE_DISCONNECT_DEBOUNCE
}
}
.stateIn(
scope = viewModelScope,
started = SharingStarted.Eagerly,
initialValue = ServiceState.Disconnected
)


companion object {
private val SERVICE_DISCONNECT_DEBOUNCE = 1.seconds
}
}

sealed interface ServiceState {
Expand Down

0 comments on commit 5e79902

Please sign in to comment.