diff options
| author | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2026-02-13 10:22:53 +0100 |
|---|---|---|
| committer | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2026-02-13 10:51:48 +0100 |
| commit | a9a169c0222d741056dfbb4d98dbe8de77e2d002 (patch) | |
| tree | c13eaa97507976bb3f80d90f46794a448bdaec65 | |
| parent | f03d6437ca6070407a2adbb1e50e6ba761e0c429 (diff) | |
| download | mullvadvpn-a9a169c0222d741056dfbb4d98dbe8de77e2d002.tar.xz mullvadvpn-a9a169c0222d741056dfbb4d98dbe8de77e2d002.zip | |
Refactor connect into feature module
67 files changed, 271 insertions, 499 deletions
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index c89d94be8e..29d3b45aa9 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -397,6 +397,7 @@ dependencies { implementation(projects.lib.feature.customlist.impl) implementation(projects.lib.feature.daita.impl) implementation(projects.lib.feature.filter.impl) + implementation(projects.lib.feature.home.impl) implementation(projects.lib.feature.login.impl) implementation(projects.lib.feature.managedevices.impl) implementation(projects.lib.feature.multihop.impl) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ExternalActionButton.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ExternalActionButton.kt deleted file mode 100644 index 7b7c092205..0000000000 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ExternalActionButton.kt +++ /dev/null @@ -1,74 +0,0 @@ -package net.mullvad.mullvadvpn.compose.button - -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.rounded.OpenInNew -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import net.mullvad.mullvadvpn.lib.ui.designsystem.VariantButton -import net.mullvad.mullvadvpn.lib.ui.theme.AppTheme - -@Preview -@Composable -private fun PreviewExternalButtonEnabled() { - AppTheme { ExternalButton(onClick = {}, text = "Button", isEnabled = true) } -} - -@Preview -@Composable -private fun PreviewExternalButtonDisabled() { - AppTheme { ExternalButton(onClick = {}, text = "Button", isEnabled = false) } -} - -@Preview -@Composable -private fun PreviewExternalButtonLongText() { - AppTheme { - ExternalButton( - onClick = {}, - text = "Button text is long and is trying to take up space that is large", - isEnabled = true, - ) - } -} - -@Preview -@Composable -private fun PreviewExternalButtonSpinner() { - AppTheme { - ExternalButton( - onClick = {}, - text = "Button text is long and is trying to take up space that is large", - isEnabled = true, - isLoading = true, - ) - } -} - -@Composable -fun ExternalButton( - onClick: () -> Unit, - text: String, - modifier: Modifier = Modifier, - isEnabled: Boolean = true, - isLoading: Boolean = false, -) { - VariantButton( - text = text, - onClick = onClick, - modifier = modifier, - isEnabled = isEnabled, - isLoading = isLoading, - icon = { - if (!isLoading) { - Icon( - imageVector = Icons.AutoMirrored.Rounded.OpenInNew, - tint = MaterialTheme.colorScheme.onTertiary, - contentDescription = null, - ) - } - }, - ) -} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/MullvadSegmentedButton.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/MullvadSegmentedButton.kt deleted file mode 100644 index 9a854dc2da..0000000000 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/MullvadSegmentedButton.kt +++ /dev/null @@ -1,121 +0,0 @@ -package net.mullvad.mullvadvpn.compose.button - -import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.SegmentedButton -import androidx.compose.material3.SegmentedButtonDefaults -import androidx.compose.material3.SingleChoiceSegmentedButtonRow -import androidx.compose.material3.SingleChoiceSegmentedButtonRowScope -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.graphics.compositeOver -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import net.mullvad.mullvadvpn.lib.ui.theme.AppTheme -import net.mullvad.mullvadvpn.lib.ui.theme.color.onSelected -import net.mullvad.mullvadvpn.lib.ui.theme.color.selected - -@Preview -@Composable -private fun PreviewMullvadSegmentedButton() { - AppTheme { - SingleChoiceSegmentedButtonRow { - MullvadSegmentedStartButton(selected = true, text = "Start", onClick = {}) - MullvadSegmentedMiddleButton(selected = false, text = "Middle", onClick = {}) - MullvadSegmentedEndButton(selected = false, text = "End", onClick = {}) - } - } -} - -@Composable -private fun SingleChoiceSegmentedButtonRowScope.MullvadSegmentedButton( - selected: Boolean, - text: String, - onClick: () -> Unit, - shape: Shape, - selectedProgress: Float = 1f, -) { - SegmentedButton( - onClick = onClick, - selected = selected, - colors = - SegmentedButtonDefaults.colors() - .copy( - activeContainerColor = - MaterialTheme.colorScheme.selected - .copy(alpha = selectedProgress) - .compositeOver(MaterialTheme.colorScheme.primary), - activeContentColor = - MaterialTheme.colorScheme.onSelected - .copy(alpha = selectedProgress) - .compositeOver(MaterialTheme.colorScheme.onPrimary), - inactiveContainerColor = MaterialTheme.colorScheme.primary, - inactiveContentColor = MaterialTheme.colorScheme.onPrimary, - ), - border = BorderStroke(0.dp, Color.Unspecified), - label = { - Text( - text = text, - textAlign = TextAlign.Center, - style = MaterialTheme.typography.titleMedium, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - }, - icon = {}, - shape = shape, - ) -} - -@Composable -fun SingleChoiceSegmentedButtonRowScope.MullvadSegmentedStartButton( - selected: Boolean, - selectedProgress: Float = 1f, - text: String, - onClick: () -> Unit, -) { - MullvadSegmentedButton( - selected = selected, - selectedProgress = selectedProgress, - text = text, - onClick = onClick, - shape = RoundedCornerShape(topStart = 8.dp, bottomStart = 8.dp), - ) -} - -@Composable -fun SingleChoiceSegmentedButtonRowScope.MullvadSegmentedMiddleButton( - selected: Boolean, - selectedProgress: Float = 1f, - text: String, - onClick: () -> Unit, -) { - MullvadSegmentedButton( - selected = selected, - selectedProgress = selectedProgress, - text = text, - onClick = onClick, - shape = RoundedCornerShape(0.dp), // Square - ) -} - -@Composable -fun SingleChoiceSegmentedButtonRowScope.MullvadSegmentedEndButton( - selected: Boolean, - selectedProgress: Float = 1f, - text: String, - onClick: () -> Unit, -) { - MullvadSegmentedButton( - selected = selected, - selectedProgress = selectedProgress, - text = text, - onClick = onClick, - shape = RoundedCornerShape(topEnd = 8.dp, bottomEnd = 8.dp), - ) -} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/SelectObfuscationCellPreviewParameterProvider.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/SelectObfuscationCellPreviewParameterProvider.kt deleted file mode 100644 index 646d4eb6e4..0000000000 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/SelectObfuscationCellPreviewParameterProvider.kt +++ /dev/null @@ -1,23 +0,0 @@ -package net.mullvad.mullvadvpn.compose.preview - -import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import net.mullvad.mullvadvpn.lib.model.Constraint -import net.mullvad.mullvadvpn.lib.model.ObfuscationMode -import net.mullvad.mullvadvpn.lib.model.Port - -class SelectObfuscationCellPreviewParameterProvider : - PreviewParameterProvider<Triple<ObfuscationMode, Constraint<Port>, Boolean>> { - override val values: Sequence<Triple<ObfuscationMode, Constraint<Port>, Boolean>> = - sequenceOf( - Triple(ObfuscationMode.Shadowsocks, Constraint.Any, false), - Triple(ObfuscationMode.Shadowsocks, Constraint.Any, true), - Triple(ObfuscationMode.Shadowsocks, Constraint.Only(Port(PORT)), false), - Triple(ObfuscationMode.Shadowsocks, Constraint.Only(Port(PORT)), true), - Triple(ObfuscationMode.Udp2Tcp, Constraint.Any, false), - Triple(ObfuscationMode.Udp2Tcp, Constraint.Any, true), - Triple(ObfuscationMode.Udp2Tcp, Constraint.Only(Port(PORT)), false), - Triple(ObfuscationMode.Udp2Tcp, Constraint.Only(Port(PORT)), true), - ) -} - -private const val PORT = 44 diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/ShadowsocksSettingsUiStatePreviewParameterProvider.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/ShadowsocksSettingsUiStatePreviewParameterProvider.kt deleted file mode 100644 index c01a12f0f6..0000000000 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/ShadowsocksSettingsUiStatePreviewParameterProvider.kt +++ /dev/null @@ -1,18 +0,0 @@ -package net.mullvad.mullvadvpn.compose.preview - -import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import net.mullvad.mullvadvpn.compose.state.ShadowsocksSettingsUiState -import net.mullvad.mullvadvpn.lib.common.Lc -import net.mullvad.mullvadvpn.lib.common.toLc -import net.mullvad.mullvadvpn.lib.model.Constraint -import net.mullvad.mullvadvpn.lib.model.Port - -class ShadowsocksSettingsUiStatePreviewParameterProvider : - PreviewParameterProvider<Lc<Unit, ShadowsocksSettingsUiState>> { - override val values: Sequence<Lc<Unit, ShadowsocksSettingsUiState>> = - sequenceOf( - Lc.Loading(Unit), - ShadowsocksSettingsUiState(port = Constraint.Any).toLc(), - ShadowsocksSettingsUiState(port = Constraint.Only(Port(1)), customPort = Port(1)).toLc(), - ) -} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MullvadApp.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MullvadApp.kt index 9e823c7682..ec354d8104 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MullvadApp.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MullvadApp.kt @@ -1,15 +1,12 @@ package net.mullvad.mullvadvpn.compose.screen -import androidx.compose.animation.AnimatedVisibilityScope import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.animation.SharedTransitionLayout -import androidx.compose.animation.SharedTransitionScope import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.semantics.semantics @@ -48,6 +45,12 @@ import com.ramcosta.composedestinations.generated.daita.destinations.DaitaDirect import com.ramcosta.composedestinations.generated.daita.destinations.DaitaDirectOnlyInfoDestination import com.ramcosta.composedestinations.generated.destinations.NoDaemonDestination import com.ramcosta.composedestinations.generated.filter.destinations.FilterDestination +import com.ramcosta.composedestinations.generated.home.destinations.Android16UpgradeWarningInfoDestination +import com.ramcosta.composedestinations.generated.home.destinations.ConnectDestination +import com.ramcosta.composedestinations.generated.home.destinations.DeviceNameInfoDestination +import com.ramcosta.composedestinations.generated.home.destinations.DeviceRevokedDestination +import com.ramcosta.composedestinations.generated.home.destinations.OutOfTimeDestination +import com.ramcosta.composedestinations.generated.home.destinations.WelcomeDestination import com.ramcosta.composedestinations.generated.login.destinations.ApiUnreachableInfoDestination import com.ramcosta.composedestinations.generated.login.destinations.CreateAccountConfirmationDestination import com.ramcosta.composedestinations.generated.login.destinations.DeviceListDestination @@ -82,19 +85,17 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.navigation.dependency import com.ramcosta.composedestinations.rememberNavHostEngine import com.ramcosta.composedestinations.utils.rememberDestinationsNavigator +import net.mullvad.mullvadvpn.common.compose.LocalSharedTransitionScope import net.mullvad.mullvadvpn.common.compose.accessibilityDataSensitive import net.mullvad.mullvadvpn.util.BackstackObserver import net.mullvad.mullvadvpn.viewmodel.DaemonScreenEvent import net.mullvad.mullvadvpn.viewmodel.MullvadAppViewModel import org.koin.androidx.compose.koinViewModel -val LocalNavAnimatedVisibilityScope = compositionLocalOf<AnimatedVisibilityScope?> { null } -@OptIn(ExperimentalSharedTransitionApi::class) -val LocalSharedTransitionScope = compositionLocalOf<SharedTransitionScope?> { null } - @NavHostGraph annotation class MainGraph { @ExternalDestination<AccountDestination> + @ExternalDestination<Android16UpgradeWarningInfoDestination> @ExternalDestination<AntiCensorshipSettingsDestination> @ExternalDestination<ApiAccessListDestination> @ExternalDestination<ApiAccessMethodDetailsDestination> @@ -104,6 +105,7 @@ annotation class MainGraph { @ExternalDestination<AppearanceDestination> @ExternalDestination<AutoConnectAndLockdownModeDestination> @ExternalDestination<ChangelogDestination> + @ExternalDestination<ConnectDestination> @ExternalDestination<ConnectOnStartupInfoDestination> @ExternalDestination<ContentBlockersInfoDestination> @ExternalDestination<CreateAccountConfirmationDestination> @@ -119,6 +121,8 @@ annotation class MainGraph { @ExternalDestination<DeleteCustomListDestination> @ExternalDestination<DeviceIpInfoDestination> @ExternalDestination<DeviceListDestination> + @ExternalDestination<DeviceNameInfoDestination> + @ExternalDestination<DeviceRevokedDestination> @ExternalDestination<DiscardApiAccessChangesDestination> @ExternalDestination<DiscardChangesDestination> @ExternalDestination<DnsDestination> @@ -136,6 +140,7 @@ annotation class MainGraph { @ExternalDestination<MtuDestination> @ExternalDestination<MultihopDestination> @ExternalDestination<NotificationSettingsDestination> + @ExternalDestination<OutOfTimeDestination> @ExternalDestination<QuantumResistanceInfoDestination> @ExternalDestination<RedeemVoucherDestination> @ExternalDestination<RemoveDeviceConfirmationDestination> @@ -151,6 +156,7 @@ annotation class MainGraph { @ExternalDestination<VerificationPendingDestination> @ExternalDestination<ViewLogsDestination> @ExternalDestination<VpnSettingsDestination> + @ExternalDestination<WelcomeDestination> companion object Includes } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplashScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplashScreen.kt index 4c87d0088e..a57e59f5cb 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplashScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplashScreen.kt @@ -19,10 +19,10 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.generated.NavGraphs -import com.ramcosta.composedestinations.generated.destinations.ConnectDestination -import com.ramcosta.composedestinations.generated.destinations.DeviceRevokedDestination -import com.ramcosta.composedestinations.generated.destinations.OutOfTimeDestination import com.ramcosta.composedestinations.generated.destinations.PrivacyDisclaimerDestination +import com.ramcosta.composedestinations.generated.home.destinations.ConnectDestination +import com.ramcosta.composedestinations.generated.home.destinations.DeviceRevokedDestination +import com.ramcosta.composedestinations.generated.home.destinations.OutOfTimeDestination import com.ramcosta.composedestinations.generated.login.destinations.LoginDestination import com.ramcosta.composedestinations.navigation.DestinationsNavigator import net.mullvad.mullvadvpn.R diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/ConnectNotificationState.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/ConnectNotificationState.kt deleted file mode 100644 index 8439680500..0000000000 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/ConnectNotificationState.kt +++ /dev/null @@ -1 +0,0 @@ -package net.mullvad.mullvadvpn.compose.state diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/ShadowsocksSettingsUiState.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/ShadowsocksSettingsUiState.kt deleted file mode 100644 index 351f7e1e02..0000000000 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/ShadowsocksSettingsUiState.kt +++ /dev/null @@ -1,11 +0,0 @@ -package net.mullvad.mullvadvpn.compose.state - -import net.mullvad.mullvadvpn.lib.model.Constraint -import net.mullvad.mullvadvpn.lib.model.Port - -data class ShadowsocksSettingsUiState( - val port: Constraint<Port> = Constraint.Any, - val customPort: Port? = null, -) { - val isCustom = port is Constraint.Only && port.value == customPort -} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/util/Navigation.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/util/Navigation.kt deleted file mode 100644 index 0d08e331e9..0000000000 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/util/Navigation.kt +++ /dev/null @@ -1,17 +0,0 @@ -package net.mullvad.mullvadvpn.compose.util - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisallowComposableCalls -import com.ramcosta.composedestinations.result.NavResult -import com.ramcosta.composedestinations.result.ResultRecipient -import com.ramcosta.composedestinations.spec.DestinationSpec - -@Composable -fun <D : DestinationSpec, V> ResultRecipient<D, V>.OnNavResultValue( - onValue: @DisallowComposableCalls (value: V) -> Unit -) = onNavResult { - when (it) { - NavResult.Canceled -> Unit - is NavResult.Value -> onValue(it.value) - } -} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt index 81e5e1366c..0ab1caca5a 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt @@ -28,6 +28,11 @@ import net.mullvad.mullvadvpn.feature.account.impl.AccountViewModel import net.mullvad.mullvadvpn.feature.addtime.impl.AddTimeViewModel import net.mullvad.mullvadvpn.feature.autoconnect.impl.AutoConnectAndLockdownModeViewModel import net.mullvad.mullvadvpn.feature.daita.impl.DaitaViewModel +import net.mullvad.mullvadvpn.feature.home.impl.connect.ConnectViewModel +import net.mullvad.mullvadvpn.feature.home.impl.connect.notificationbanner.InAppNotificationController +import net.mullvad.mullvadvpn.feature.home.impl.devicerevoked.DeviceRevokedViewModel +import net.mullvad.mullvadvpn.feature.home.impl.outoftime.OutOfTimeViewModel +import net.mullvad.mullvadvpn.feature.home.impl.welcome.WelcomeViewModel import net.mullvad.mullvadvpn.feature.login.impl.LoginViewModel import net.mullvad.mullvadvpn.feature.login.impl.apiunreachable.ApiUnreachableViewModel import net.mullvad.mullvadvpn.feature.login.impl.devicelist.DeviceListViewModel @@ -97,19 +102,14 @@ import net.mullvad.mullvadvpn.lib.usecase.inappnotification.TunnelStateNotificat import net.mullvad.mullvadvpn.lib.usecase.inappnotification.VersionNotificationUseCase import net.mullvad.mullvadvpn.multihop.impl.MultihopViewModel import net.mullvad.mullvadvpn.receiver.AutoStartVpnBootCompletedReceiver -import net.mullvad.mullvadvpn.repository.InAppNotificationController import net.mullvad.mullvadvpn.serveripoverride.impl.ServerIpOverridesViewModel import net.mullvad.mullvadvpn.serveripoverride.impl.reset.ResetServerIpOverridesConfirmationViewModel import net.mullvad.mullvadvpn.ui.MainActivity import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager import net.mullvad.mullvadvpn.util.BackstackObserver -import net.mullvad.mullvadvpn.viewmodel.ConnectViewModel -import net.mullvad.mullvadvpn.viewmodel.DeviceRevokedViewModel import net.mullvad.mullvadvpn.viewmodel.MullvadAppViewModel -import net.mullvad.mullvadvpn.viewmodel.OutOfTimeViewModel import net.mullvad.mullvadvpn.viewmodel.PrivacyDisclaimerViewModel import net.mullvad.mullvadvpn.viewmodel.SplashViewModel -import net.mullvad.mullvadvpn.viewmodel.WelcomeViewModel import net.mullvad.mullvadvpn.viewmodel.location.LocationBottomSheetViewModel import net.mullvad.mullvadvpn.viewmodel.location.SearchLocationViewModel import net.mullvad.mullvadvpn.viewmodel.location.SelectLocationListViewModel diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt index b6af4b4fae..a3ff3255cc 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt @@ -22,10 +22,10 @@ import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import net.mullvad.mullvadvpn.compose.screen.MullvadApp -import net.mullvad.mullvadvpn.compose.util.CreateVpnProfile import net.mullvad.mullvadvpn.di.paymentModule import net.mullvad.mullvadvpn.di.uiModule import net.mullvad.mullvadvpn.lib.common.constant.KEY_REQUEST_VPN_PROFILE +import net.mullvad.mullvadvpn.lib.common.util.CreateVpnProfile import net.mullvad.mullvadvpn.lib.common.util.SdkUtils.requestNotificationPermissionIfMissing import net.mullvad.mullvadvpn.lib.common.util.prepareVpnSafe import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointFromIntentHolder diff --git a/android/lib/common-compose/src/main/kotlin/net/mullvad/mullvadvpn/common/compose/Shared.kt b/android/lib/common-compose/src/main/kotlin/net/mullvad/mullvadvpn/common/compose/Shared.kt new file mode 100644 index 0000000000..fe9f0a99de --- /dev/null +++ b/android/lib/common-compose/src/main/kotlin/net/mullvad/mullvadvpn/common/compose/Shared.kt @@ -0,0 +1,10 @@ +package net.mullvad.mullvadvpn.common.compose + +import androidx.compose.animation.AnimatedVisibilityScope +import androidx.compose.animation.ExperimentalSharedTransitionApi +import androidx.compose.animation.SharedTransitionScope +import androidx.compose.runtime.compositionLocalOf + +val LocalNavAnimatedVisibilityScope = compositionLocalOf<AnimatedVisibilityScope?> { null } +@OptIn(ExperimentalSharedTransitionApi::class) +val LocalSharedTransitionScope = compositionLocalOf<SharedTransitionScope?> { null } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/util/CreateVpnProfile.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/CreateVpnProfile.kt index 750ca6485c..2f1b6167d9 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/util/CreateVpnProfile.kt +++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/CreateVpnProfile.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.util +package net.mullvad.mullvadvpn.lib.common.util import android.app.Activity import android.content.Context diff --git a/android/lib/feature/account/impl/build.gradle.kts b/android/lib/feature/account/impl/build.gradle.kts index 6c61b92961..8c99f8daa0 100644 --- a/android/lib/feature/account/impl/build.gradle.kts +++ b/android/lib/feature/account/impl/build.gradle.kts @@ -16,6 +16,7 @@ dependencies { implementation(projects.lib.repository) implementation(projects.lib.payment) implementation(projects.lib.feature.addtime.impl) + implementation(projects.lib.feature.login.impl) implementation(projects.lib.feature.managedevices.impl) implementation(projects.lib.feature.redeemvoucher.impl) diff --git a/android/lib/feature/account/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/account/impl/AccountScreen.kt b/android/lib/feature/account/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/account/impl/AccountScreen.kt index 30a6e5bfd7..477c79bb97 100644 --- a/android/lib/feature/account/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/account/impl/AccountScreen.kt +++ b/android/lib/feature/account/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/account/impl/AccountScreen.kt @@ -35,9 +35,11 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.LayoutDirection import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.dropUnlessResumed +import androidx.navigation.NavController import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.ExternalModuleGraph import com.ramcosta.composedestinations.generated.addtime.destinations.VerificationPendingDestination +import com.ramcosta.composedestinations.generated.login.destinations.LoginDestination import com.ramcosta.composedestinations.generated.managedevices.destinations.ManageDevicesDestination import com.ramcosta.composedestinations.generated.redeemvoucher.destinations.RedeemVoucherDestination import com.ramcosta.composedestinations.navigation.DestinationsNavigator @@ -84,7 +86,7 @@ private fun PreviewAccountScreen( @OptIn(ExperimentalMaterial3Api::class) @Destination<ExternalModuleGraph>(style = AccountTransition::class) @Composable -fun Account(navigator: DestinationsNavigator) { +fun Account(navController: NavController, navigator: DestinationsNavigator) { val vm = koinViewModel<AccountViewModel>() val state by vm.uiState.collectAsStateWithLifecycle() @@ -98,11 +100,10 @@ fun Account(navigator: DestinationsNavigator) { CollectSideEffectWithLifecycle(vm.uiSideEffect) { sideEffect -> when (sideEffect) { AccountViewModel.UiSideEffect.NavigateToLogin -> { - // TODO How to solve this? - /*navigator.navigate(LoginDestination(null)) { + navController.navigate(LoginDestination.route) { launchSingleTop = true - popUpTo(NavGraphs.main) { inclusive = true } - }*/ + popUpTo("main") { inclusive = true } + } } is AccountViewModel.UiSideEffect.OpenAccountManagementPageInBrowser -> openAccountPage(sideEffect.token) diff --git a/android/lib/feature/home/impl/build.gradle.kts b/android/lib/feature/home/impl/build.gradle.kts new file mode 100644 index 0000000000..132ee9b12e --- /dev/null +++ b/android/lib/feature/home/impl/build.gradle.kts @@ -0,0 +1,50 @@ +plugins { + alias(libs.plugins.mullvad.android.library) + alias(libs.plugins.mullvad.android.library.feature.impl) + alias(libs.plugins.mullvad.android.library.compose) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.parcelize) + alias(libs.plugins.kotlin.ksp) +} + +android { + namespace = "net.mullvad.mullvadvpn.feature.home.impl" + ksp { arg("compose-destinations.moduleName", "home") } +} + +dependencies { + implementation(projects.lib.map) + implementation(projects.lib.payment) + implementation(projects.lib.pushNotification) + implementation(projects.lib.repository) + implementation(projects.lib.tv) + implementation(projects.lib.usecase) + implementation(projects.lib.feature.account.impl) + implementation(projects.lib.feature.addtime.impl) + implementation(projects.lib.feature.anticensorship.impl) + implementation(projects.lib.feature.appinfo.impl) + implementation(projects.lib.feature.daita.impl) + implementation(projects.lib.feature.login.impl) + implementation(projects.lib.feature.multihop.impl) + implementation(projects.lib.feature.redeemvoucher.impl) + implementation(projects.lib.feature.serveripoverride.impl) + implementation(projects.lib.feature.settings.impl) + implementation(projects.lib.feature.splittunneling.impl) + implementation(projects.lib.feature.vpnsettings.impl) + + implementation(libs.androidx.animation) + implementation(libs.koin.compose) + implementation(libs.arrow) + implementation(libs.compose.constrainlayout) + implementation(libs.androidx.credentials) { + // This dependency adds a lot of unused permissions to the app. + // It is not used so let's exclude it. + // Unfortunately, this is not possible to do using libs.version.toml + // https://github.com/gradle/gradle/issues/26367#issuecomment-2120830998 + exclude("androidx.biometric", "biometric") + } + + // Destinations + implementation(libs.compose.destinations) + ksp(libs.compose.destinations.ksp) +} diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt b/android/lib/feature/home/impl/src/androidTest/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectScreenTest.kt index 3a93a9361a..defb896fd8 100644 --- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt +++ b/android/lib/feature/home/impl/src/androidTest/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectScreenTest.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.screen +package net.mullvad.mullvadvpn.feature.home.impl.connect import androidx.compose.ui.test.ExperimentalTestApi import androidx.compose.ui.test.onNodeWithTag @@ -13,7 +13,6 @@ import io.mockk.verify import java.time.Duration import java.time.Instant import java.time.ZonedDateTime -import net.mullvad.mullvadvpn.compose.state.ConnectUiState import net.mullvad.mullvadvpn.lib.model.ActionAfterDisconnect import net.mullvad.mullvadvpn.lib.model.ErrorState import net.mullvad.mullvadvpn.lib.model.ErrorStateCause diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreenTest.kt b/android/lib/feature/home/impl/src/androidTest/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedScreenTest.kt index 159c26e420..8b5c2af47e 100644 --- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreenTest.kt +++ b/android/lib/feature/home/impl/src/androidTest/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedScreenTest.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.screen +package net.mullvad.mullvadvpn.feature.home.impl.devicerevoked import androidx.compose.ui.test.ExperimentalTestApi import androidx.compose.ui.test.onNodeWithText @@ -7,7 +7,6 @@ import de.mannodermaus.junit5.compose.ComposeContext import io.mockk.MockKAnnotations import io.mockk.mockk import io.mockk.verify -import net.mullvad.mullvadvpn.compose.state.DeviceRevokedUiState import net.mullvad.mullvadvpn.screen.test.createEdgeToEdgeComposeExtension import net.mullvad.mullvadvpn.screen.test.setContentWithTheme import org.junit.jupiter.api.BeforeEach diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreenTest.kt b/android/lib/feature/home/impl/src/androidTest/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeScreenTest.kt index 6941b96c1f..19d0977cb9 100644 --- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreenTest.kt +++ b/android/lib/feature/home/impl/src/androidTest/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeScreenTest.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.screen +package net.mullvad.mullvadvpn.feature.home.impl.outoftime import androidx.compose.ui.test.ExperimentalTestApi import androidx.compose.ui.test.onNodeWithContentDescription @@ -11,7 +11,6 @@ import io.mockk.every import io.mockk.mockk import io.mockk.verify import kotlinx.coroutines.flow.MutableStateFlow -import net.mullvad.mullvadvpn.compose.state.OutOfTimeUiState import net.mullvad.mullvadvpn.feature.addtime.impl.AddTimeUiState import net.mullvad.mullvadvpn.feature.addtime.impl.AddTimeViewModel import net.mullvad.mullvadvpn.lib.common.Lc diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreenTest.kt b/android/lib/feature/home/impl/src/androidTest/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeScreenTest.kt index 11ffab3985..c4553d3193 100644 --- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreenTest.kt +++ b/android/lib/feature/home/impl/src/androidTest/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeScreenTest.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.screen +package net.mullvad.mullvadvpn.feature.home.impl.welcome import androidx.compose.ui.test.ExperimentalTestApi import androidx.compose.ui.test.onNodeWithTag @@ -10,7 +10,6 @@ import io.mockk.every import io.mockk.mockk import io.mockk.verify import kotlinx.coroutines.flow.MutableStateFlow -import net.mullvad.mullvadvpn.compose.state.WelcomeUiState import net.mullvad.mullvadvpn.feature.addtime.impl.AddTimeUiState import net.mullvad.mullvadvpn.feature.addtime.impl.AddTimeViewModel import net.mullvad.mullvadvpn.lib.common.Lc diff --git a/android/lib/feature/home/impl/src/main/AndroidManifest.xml b/android/lib/feature/home/impl/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..8bdb7e14b3 --- /dev/null +++ b/android/lib/feature/home/impl/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android"> + +</manifest> diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/transitions/HomeTransition.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/HomeTransition.kt index 91388630c3..0256c4e21c 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/transitions/HomeTransition.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/HomeTransition.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.transitions +package net.mullvad.mullvadvpn.feature.home.impl import androidx.compose.animation.AnimatedContentTransitionScope import androidx.compose.animation.EnterTransition @@ -7,7 +7,6 @@ import androidx.compose.animation.fadeIn import androidx.navigation.NavBackStackEntry import com.ramcosta.composedestinations.generated.login.destinations.LoginDestination import com.ramcosta.composedestinations.spec.DestinationStyle -import com.ramcosta.composedestinations.utils.destination // This is used for OutOfTime, Welcome, and Connect destinations. object HomeTransition : DestinationStyle.Animated() { @@ -15,7 +14,8 @@ object HomeTransition : DestinationStyle.Animated() { override val enterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition = { - when (initialState.destination()) { + fadeIn() + when (initialState.destination) { LoginDestination -> fadeIn() else -> EnterTransition.None } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/TunnelStatePreviewData.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/TunnelStatePreviewData.kt index a35de85e4c..f3dd7f33b6 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/TunnelStatePreviewData.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/TunnelStatePreviewData.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.preview +package net.mullvad.mullvadvpn.feature.home.impl import java.net.InetSocketAddress import net.mullvad.mullvadvpn.lib.model.ActionAfterDisconnect diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/info/Android16UpgradeWarningInfoDialog.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/Android16UpgradeWarningInfoDialog.kt index 7d3fe27ced..8f56fbae85 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/info/Android16UpgradeWarningInfoDialog.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/Android16UpgradeWarningInfoDialog.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.dialog.info +package net.mullvad.mullvadvpn.feature.home.impl.connect import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable @@ -7,13 +7,13 @@ import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.tooling.preview.Preview import com.ramcosta.composedestinations.annotation.Destination +import com.ramcosta.composedestinations.annotation.ExternalModuleGraph import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.spec.DestinationStyle -import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.common.compose.clickableAnnotatedString import net.mullvad.mullvadvpn.common.compose.createCopyToClipboardHandle -import net.mullvad.mullvadvpn.compose.screen.MainGraph import net.mullvad.mullvadvpn.lib.ui.component.dialog.InfoDialog +import net.mullvad.mullvadvpn.lib.ui.resource.R import net.mullvad.mullvadvpn.lib.ui.theme.AppTheme @Preview @@ -22,7 +22,7 @@ private fun PreviewAndroid16UpgradeWarningInfoDialog() { AppTheme { Android16UpgradeWarningInfoDialog(onDismiss = {}, onClickEmail = {}) } } -@Destination<MainGraph>(style = DestinationStyle.Dialog::class) +@Destination<ExternalModuleGraph>(style = DestinationStyle.Dialog::class) @Composable fun Android16UpgradeWarningInfo(navigator: DestinationsNavigator) { val copyToClipboard = createCopyToClipboardHandle(isSensitive = false) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectScreen.kt index f82d19e732..74a3c2e5a8 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectScreen.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.screen +package net.mullvad.mullvadvpn.feature.home.impl.connect import android.content.res.Resources import androidx.activity.compose.rememberLauncherForActivityResult @@ -64,27 +64,26 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.dropUnlessResumed +import androidx.navigation.NavController import com.ramcosta.composedestinations.annotation.Destination -import com.ramcosta.composedestinations.generated.NavGraphs +import com.ramcosta.composedestinations.annotation.ExternalModuleGraph import com.ramcosta.composedestinations.generated.account.destinations.AccountDestination import com.ramcosta.composedestinations.generated.anticensorship.destinations.AntiCensorshipSettingsDestination import com.ramcosta.composedestinations.generated.appinfo.destinations.ChangelogDestination import com.ramcosta.composedestinations.generated.daita.destinations.DaitaDestination -import com.ramcosta.composedestinations.generated.destinations.Android16UpgradeWarningInfoDestination -import com.ramcosta.composedestinations.generated.destinations.DeviceRevokedDestination -import com.ramcosta.composedestinations.generated.destinations.OutOfTimeDestination -import com.ramcosta.composedestinations.generated.destinations.SelectLocationDestination +import com.ramcosta.composedestinations.generated.home.destinations.Android16UpgradeWarningInfoDestination +import com.ramcosta.composedestinations.generated.home.destinations.DeviceRevokedDestination +import com.ramcosta.composedestinations.generated.home.destinations.OutOfTimeDestination import com.ramcosta.composedestinations.generated.multihop.destinations.MultihopDestination import com.ramcosta.composedestinations.generated.serveripoverride.destinations.ServerIpOverridesDestination import com.ramcosta.composedestinations.generated.settings.destinations.SettingsDestination import com.ramcosta.composedestinations.generated.splittunneling.destinations.SplitTunnelingDestination import com.ramcosta.composedestinations.generated.vpnsettings.destinations.VpnSettingsDestination import com.ramcosta.composedestinations.navigation.DestinationsNavigator -import com.ramcosta.composedestinations.result.ResultRecipient import kotlinx.coroutines.launch -import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.appinfo.impl.changelog.ChangelogNavArgs import net.mullvad.mullvadvpn.common.compose.CollectSideEffectWithLifecycle +import net.mullvad.mullvadvpn.common.compose.LocalNavAnimatedVisibilityScope import net.mullvad.mullvadvpn.common.compose.SECURE_ZOOM import net.mullvad.mullvadvpn.common.compose.SECURE_ZOOM_ANIMATION_MILLIS import net.mullvad.mullvadvpn.common.compose.UNSECURE_ZOOM @@ -94,18 +93,14 @@ import net.mullvad.mullvadvpn.common.compose.fallbackLatLong import net.mullvad.mullvadvpn.common.compose.isTv import net.mullvad.mullvadvpn.common.compose.safeOpenUri import net.mullvad.mullvadvpn.common.compose.showSnackbarImmediately -import net.mullvad.mullvadvpn.compose.button.ConnectionButton -import net.mullvad.mullvadvpn.compose.button.SwitchLocationButton -import net.mullvad.mullvadvpn.compose.component.ConnectionStatusText -import net.mullvad.mullvadvpn.compose.component.connectioninfo.ConnectionDetailPanel -import net.mullvad.mullvadvpn.compose.component.connectioninfo.FeatureIndicatorsPanel -import net.mullvad.mullvadvpn.compose.component.connectioninfo.toInAddress -import net.mullvad.mullvadvpn.compose.component.notificationbanner.NotificationBanner -import net.mullvad.mullvadvpn.compose.preview.ConnectUiStatePreviewParameterProvider -import net.mullvad.mullvadvpn.compose.state.ConnectUiState -import net.mullvad.mullvadvpn.compose.transitions.HomeTransition -import net.mullvad.mullvadvpn.compose.util.CreateVpnProfile -import net.mullvad.mullvadvpn.core.OnNavResultValue +import net.mullvad.mullvadvpn.feature.home.impl.HomeTransition +import net.mullvad.mullvadvpn.feature.home.impl.connect.button.ConnectionButton +import net.mullvad.mullvadvpn.feature.home.impl.connect.button.SwitchLocationButton +import net.mullvad.mullvadvpn.feature.home.impl.connect.connectioninfo.ConnectionDetailPanel +import net.mullvad.mullvadvpn.feature.home.impl.connect.connectioninfo.FeatureIndicatorsPanel +import net.mullvad.mullvadvpn.feature.home.impl.connect.connectioninfo.toInAddress +import net.mullvad.mullvadvpn.feature.home.impl.connect.notificationbanner.NotificationBanner +import net.mullvad.mullvadvpn.lib.common.util.CreateVpnProfile import net.mullvad.mullvadvpn.lib.common.util.openVpnSettings import net.mullvad.mullvadvpn.lib.common.util.removeHtmlTags import net.mullvad.mullvadvpn.lib.map.AnimatedMap @@ -125,6 +120,7 @@ import net.mullvad.mullvadvpn.lib.ui.component.ScaffoldWithTopBarAndDeviceName import net.mullvad.mullvadvpn.lib.ui.component.drawVerticalScrollbar import net.mullvad.mullvadvpn.lib.ui.designsystem.MullvadCircularProgressIndicatorLarge import net.mullvad.mullvadvpn.lib.ui.designsystem.MullvadSnackbar +import net.mullvad.mullvadvpn.lib.ui.resource.R import net.mullvad.mullvadvpn.lib.ui.tag.CONNECT_BUTTON_TEST_TAG import net.mullvad.mullvadvpn.lib.ui.tag.CONNECT_CARD_HEADER_TEST_TAG import net.mullvad.mullvadvpn.lib.ui.tag.RECONNECT_BUTTON_TEST_TAG @@ -137,7 +133,6 @@ import net.mullvad.mullvadvpn.lib.ui.theme.color.Alpha80 import net.mullvad.mullvadvpn.lib.ui.theme.color.AlphaInvisible import net.mullvad.mullvadvpn.lib.ui.theme.color.AlphaScrollbar import net.mullvad.mullvadvpn.lib.ui.theme.color.AlphaVisible -import net.mullvad.mullvadvpn.viewmodel.ConnectViewModel import org.koin.androidx.compose.koinViewModel private const val CONNECT_BUTTON_THROTTLE_MILLIS = 1000 @@ -175,12 +170,14 @@ private fun PreviewAccountScreen( } @Suppress("LongMethod") -@Destination<MainGraph>(style = HomeTransition::class) +@Destination<ExternalModuleGraph>(style = HomeTransition::class) @Composable fun Connect( + navController: NavController, navigator: DestinationsNavigator, animatedVisibilityScope: AnimatedVisibilityScope, - selectLocationResultRecipient: ResultRecipient<SelectLocationDestination, Boolean>, + // TODO Restore this when we can navigate to select location + // selectLocationResultRecipient: ResultRecipient<SelectLocationMockDestination, Boolean>, ) { val connectViewModel: ConnectViewModel = koinViewModel() @@ -207,15 +204,15 @@ fun Connect( openAccountPage(sideEffect.token) is ConnectViewModel.UiSideEffect.OutOfTime -> - navigator.navigate(OutOfTimeDestination) { + navController.navigate(OutOfTimeDestination.route) { launchSingleTop = true - popUpTo(NavGraphs.main) { inclusive = true } + popUpTo("main") { inclusive = true } } ConnectViewModel.UiSideEffect.RevokedDevice -> - navigator.navigate(DeviceRevokedDestination) { + navController.navigate(DeviceRevokedDestination.route) { launchSingleTop = true - popUpTo(NavGraphs.main) { inclusive = true } + popUpTo("main") { inclusive = true } } is ConnectViewModel.UiSideEffect.NotPrepared -> @@ -281,11 +278,12 @@ fun Connect( } } - selectLocationResultRecipient.OnNavResultValue { result -> + // TODO Restore this when we can navigate to select location + /*selectLocationResultRecipient.OnNavResultValue { result -> if (result) { connectViewModel.onConnectClick() } - } + }*/ CompositionLocalProvider(LocalNavAnimatedVisibilityScope provides animatedVisibilityScope) { ConnectScreen( @@ -295,8 +293,9 @@ fun Connect( onReconnectClick = connectViewModel::onReconnectClick, onConnectClick = connectViewModel::onConnectClick, onCancelClick = connectViewModel::onCancelClick, - onSwitchLocationClick = - dropUnlessResumed { navigator.navigate(SelectLocationDestination) }, + onSwitchLocationClick = {}, + // TODO Restore this when we can navigate to select location + // dropUnlessResumed { navigator.navigate(SelectLocationMockDestination) }, onOpenAppListing = connectViewModel::openAppListing, onManageAccountClick = connectViewModel::onManageAccountClick, onChangelogClick = diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/ConnectUiState.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectUiState.kt index 956b1506a7..2c97b44f3f 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/ConnectUiState.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectUiState.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.state +package net.mullvad.mullvadvpn.feature.home.impl.connect import net.mullvad.mullvadvpn.lib.model.GeoIpLocation import net.mullvad.mullvadvpn.lib.model.InAppNotification diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/ConnectUiStatePreviewParameterProvider.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectUiStatePreviewParameterProvider.kt index 0a332ba385..b362099faf 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/ConnectUiStatePreviewParameterProvider.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectUiStatePreviewParameterProvider.kt @@ -1,8 +1,8 @@ -package net.mullvad.mullvadvpn.compose.preview +package net.mullvad.mullvadvpn.feature.home.impl.connect import androidx.compose.ui.tooling.preview.PreviewParameterProvider import java.net.InetAddress -import net.mullvad.mullvadvpn.compose.state.ConnectUiState +import net.mullvad.mullvadvpn.feature.home.impl.TunnelStatePreviewData import net.mullvad.mullvadvpn.lib.model.ActionAfterDisconnect import net.mullvad.mullvadvpn.lib.model.GeoIpLocation import net.mullvad.mullvadvpn.lib.model.InAppNotification diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectViewModel.kt index 6e5234f09d..0e2c187ecf 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectViewModel.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.viewmodel +package net.mullvad.mullvadvpn.feature.home.impl.connect import android.content.res.Resources import android.net.Uri @@ -18,9 +18,8 @@ import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch -import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.compose.state.ConnectUiState import net.mullvad.mullvadvpn.feature.addtime.impl.isSuccess +import net.mullvad.mullvadvpn.feature.home.impl.connect.notificationbanner.InAppNotificationController import net.mullvad.mullvadvpn.lib.common.constant.VIEW_MODEL_STOP_TIMEOUT import net.mullvad.mullvadvpn.lib.common.util.combine import net.mullvad.mullvadvpn.lib.common.util.daysFromNow @@ -38,11 +37,11 @@ import net.mullvad.mullvadvpn.lib.repository.DeviceRepository import net.mullvad.mullvadvpn.lib.repository.NewDeviceRepository import net.mullvad.mullvadvpn.lib.repository.PaymentLogic import net.mullvad.mullvadvpn.lib.repository.UserPreferencesRepository +import net.mullvad.mullvadvpn.lib.ui.resource.R import net.mullvad.mullvadvpn.lib.usecase.LastKnownLocationUseCase import net.mullvad.mullvadvpn.lib.usecase.OutOfTimeUseCase import net.mullvad.mullvadvpn.lib.usecase.SelectedLocationTitleUseCase import net.mullvad.mullvadvpn.lib.usecase.SystemVpnSettingsAvailableUseCase -import net.mullvad.mullvadvpn.repository.InAppNotificationController @Suppress("LongParameterList") class ConnectViewModel( @@ -89,6 +88,7 @@ class ConnectViewModel( when (tunnelState) { is TunnelState.Disconnected -> tunnelState.location ?: lastKnownDisconnectedLocation + is TunnelState.Connecting -> tunnelState.location is TunnelState.Connected -> tunnelState.location is TunnelState.Disconnecting -> @@ -100,6 +100,7 @@ class ConnectViewModel( // location ActionAfterDisconnect.Reconnect -> prevTunnelState?.location() } + is TunnelState.Error -> lastKnownDisconnectedLocation }, selectedRelayItemTitle = diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectionStatusText.kt index 43610312c0..347202c39e 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectionStatusText.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.component +package net.mullvad.mullvadvpn.feature.home.impl.connect import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column @@ -10,10 +10,9 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter -import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewParameterProvider import net.mullvad.mullvadvpn.lib.model.ActionAfterDisconnect import net.mullvad.mullvadvpn.lib.model.TunnelState +import net.mullvad.mullvadvpn.lib.ui.resource.R import net.mullvad.mullvadvpn.lib.ui.theme.AppTheme @Preview diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/TunnelStatePreviewParameterProvider.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/TunnelStatePreviewParameterProvider.kt index f9390e9986..e9bb06d47d 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/TunnelStatePreviewParameterProvider.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/TunnelStatePreviewParameterProvider.kt @@ -1,11 +1,11 @@ -package net.mullvad.mullvadvpn.compose.preview +package net.mullvad.mullvadvpn.feature.home.impl.connect import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateConnectedState -import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateConnectingState -import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateDisconnectedState -import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateDisconnectingState -import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateErrorState +import net.mullvad.mullvadvpn.feature.home.impl.TunnelStatePreviewData.generateConnectedState +import net.mullvad.mullvadvpn.feature.home.impl.TunnelStatePreviewData.generateConnectingState +import net.mullvad.mullvadvpn.feature.home.impl.TunnelStatePreviewData.generateDisconnectedState +import net.mullvad.mullvadvpn.feature.home.impl.TunnelStatePreviewData.generateDisconnectingState +import net.mullvad.mullvadvpn.feature.home.impl.TunnelStatePreviewData.generateErrorState import net.mullvad.mullvadvpn.lib.model.ActionAfterDisconnect import net.mullvad.mullvadvpn.lib.model.TunnelState diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/button/ConnectionButton.kt index cbad605ba5..5611a61e13 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/button/ConnectionButton.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.button +package net.mullvad.mullvadvpn.feature.home.impl.connect.button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.MaterialTheme @@ -7,10 +7,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter -import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewParameterProvider +import net.mullvad.mullvadvpn.feature.home.impl.connect.TunnelStatePreviewParameterProvider import net.mullvad.mullvadvpn.lib.model.TunnelState import net.mullvad.mullvadvpn.lib.ui.designsystem.PrimaryButton +import net.mullvad.mullvadvpn.lib.ui.resource.R import net.mullvad.mullvadvpn.lib.ui.theme.AppTheme @Composable diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/SwitchLocationButton.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/button/SwitchLocationButton.kt index e26120a906..3bf8e115fe 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/SwitchLocationButton.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/button/SwitchLocationButton.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.button +package net.mullvad.mullvadvpn.feature.home.impl.connect.button import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -32,7 +32,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.constraintlayout.compose.ConstraintLayout import androidx.constraintlayout.compose.Dimension -import net.mullvad.mullvadvpn.R +import net.mullvad.mullvadvpn.lib.ui.resource.R import net.mullvad.mullvadvpn.lib.ui.theme.AppTheme import net.mullvad.mullvadvpn.lib.ui.theme.Dimens @@ -100,7 +100,7 @@ fun SwitchLocationButton( contentColor = MaterialTheme.colorScheme.onPrimary, ), modifier = - Modifier.constrainAs(connectionButton) { + Modifier.Companion.constrainAs(connectionButton) { start.linkTo(parent.start) if (isReconnectButtonEnabled) { end.linkTo(reconnectButton.start) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/connectioninfo/ConnectionDetailPanel.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/connectioninfo/ConnectionDetailPanel.kt index f593b3a632..dcc3c0b5c5 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/connectioninfo/ConnectionDetailPanel.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/connectioninfo/ConnectionDetailPanel.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.component.connectioninfo +package net.mullvad.mullvadvpn.feature.home.impl.connect.connectioninfo import androidx.compose.animation.AnimatedContent import androidx.compose.foundation.layout.Box @@ -15,11 +15,11 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.constraintlayout.compose.ConstraintLayout import androidx.constraintlayout.compose.Dimension -import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.compose.screen.ConnectionDetails +import net.mullvad.mullvadvpn.feature.home.impl.connect.ConnectionDetails import net.mullvad.mullvadvpn.lib.model.TransportProtocol import net.mullvad.mullvadvpn.lib.model.TunnelEndpoint import net.mullvad.mullvadvpn.lib.ui.component.SPACE_CHAR +import net.mullvad.mullvadvpn.lib.ui.resource.R import net.mullvad.mullvadvpn.lib.ui.tag.LOCATION_INFO_CONNECTION_IN_TEST_TAG import net.mullvad.mullvadvpn.lib.ui.tag.LOCATION_INFO_CONNECTION_OUT_TEST_TAG import net.mullvad.mullvadvpn.lib.ui.theme.Dimens @@ -92,7 +92,7 @@ fun ConnectionDetails( ) SelectionContainer( modifier = - Modifier.constrainAs(inAddr) { + Modifier.Companion.constrainAs(inAddr) { start.linkTo(headerBarrier) end.linkTo(parent.end) top.linkTo(parent.top) @@ -134,7 +134,7 @@ fun ConnectionDetails( ) Box( modifier = - Modifier.constrainAs(outAddrV4) { + Modifier.Companion.constrainAs(outAddrV4) { start.linkTo(headerBarrier) end.linkTo(parent.end) top.linkTo(inAddrBarrier) @@ -185,7 +185,7 @@ fun ConnectionDetails( ) Box( modifier = - Modifier.constrainAs(outAddrV6) { + Modifier.Companion.constrainAs(outAddrV6) { start.linkTo(headerBarrier) end.linkTo(parent.end) top.linkTo(outAddrV4Barrier) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/connectioninfo/ConnectionInfoHeader.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/connectioninfo/ConnectionInfoHeader.kt index 49a42ebc9a..c68272a667 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/connectioninfo/ConnectionInfoHeader.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/connectioninfo/ConnectionInfoHeader.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.component.connectioninfo +package net.mullvad.mullvadvpn.feature.home.impl.connect.connectioninfo import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/connectioninfo/FeatureIndicatorsPanel.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/connectioninfo/FeatureIndicatorsPanel.kt index b15c8e5473..f41634048b 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/connectioninfo/FeatureIndicatorsPanel.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/connectioninfo/FeatureIndicatorsPanel.kt @@ -1,7 +1,7 @@ @file:OptIn(ExperimentalSharedTransitionApi::class) @file:Suppress("DEPRECATION") -package net.mullvad.mullvadvpn.compose.component.connectioninfo +package net.mullvad.mullvadvpn.feature.home.impl.connect.connectioninfo import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.animation.core.EaseInQuart @@ -20,12 +20,12 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource -import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.compose.screen.LocalNavAnimatedVisibilityScope -import net.mullvad.mullvadvpn.compose.screen.LocalSharedTransitionScope +import net.mullvad.mullvadvpn.common.compose.LocalNavAnimatedVisibilityScope +import net.mullvad.mullvadvpn.common.compose.LocalSharedTransitionScope import net.mullvad.mullvadvpn.lib.model.FeatureIndicator import net.mullvad.mullvadvpn.lib.ui.designsystem.MullvadFeatureChip import net.mullvad.mullvadvpn.lib.ui.designsystem.MullvadMoreChip +import net.mullvad.mullvadvpn.lib.ui.resource.R import net.mullvad.mullvadvpn.lib.ui.theme.Dimens @Composable diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/InAppNotificationController.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/notificationbanner/InAppNotificationController.kt index 3a74348e84..a34ae04576 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/InAppNotificationController.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/notificationbanner/InAppNotificationController.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.repository +package net.mullvad.mullvadvpn.feature.home.impl.connect.notificationbanner import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted @@ -26,5 +26,5 @@ class InAppNotificationController( ) ) } - .stateIn(scope, SharingStarted.Eagerly, emptyList()) + .stateIn(scope, SharingStarted.Companion.Eagerly, emptyList()) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/notificationbanner/NotificationBanner.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/notificationbanner/NotificationBanner.kt index 67bcb1dfa5..cdc2819d7b 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/notificationbanner/NotificationBanner.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/notificationbanner/NotificationBanner.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.component.notificationbanner +package net.mullvad.mullvadvpn.feature.home.impl.connect.notificationbanner import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/DeviceRevokedLoginButton.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedLoginButton.kt index fbf360d3ba..ca86e3ae3e 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/DeviceRevokedLoginButton.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedLoginButton.kt @@ -1,11 +1,10 @@ -package net.mullvad.mullvadvpn.compose.button +package net.mullvad.mullvadvpn.feature.home.impl.devicerevoked import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource -import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.compose.state.DeviceRevokedUiState import net.mullvad.mullvadvpn.lib.ui.designsystem.NegativeButton import net.mullvad.mullvadvpn.lib.ui.designsystem.VariantButton +import net.mullvad.mullvadvpn.lib.ui.resource.R @Composable fun DeviceRevokedLoginButton(onClick: () -> Unit, state: DeviceRevokedUiState) { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreen.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedScreen.kt index 012ed00d57..cd6bf0031c 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreen.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedScreen.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.screen +package net.mullvad.mullvadvpn.feature.home.impl.devicerevoked import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -21,23 +21,19 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.dropUnlessResumed +import androidx.navigation.NavController import com.ramcosta.composedestinations.annotation.Destination -import com.ramcosta.composedestinations.generated.NavGraphs +import com.ramcosta.composedestinations.annotation.ExternalModuleGraph import com.ramcosta.composedestinations.generated.login.destinations.LoginDestination import com.ramcosta.composedestinations.generated.settings.destinations.SettingsDestination import com.ramcosta.composedestinations.navigation.DestinationsNavigator -import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.common.compose.CollectSideEffectWithLifecycle -import net.mullvad.mullvadvpn.compose.button.DeviceRevokedLoginButton -import net.mullvad.mullvadvpn.compose.preview.DeviceRevokedUiStatePreviewParameterProvider -import net.mullvad.mullvadvpn.compose.state.DeviceRevokedUiState import net.mullvad.mullvadvpn.lib.ui.component.ScaffoldWithTopBar import net.mullvad.mullvadvpn.lib.ui.component.drawVerticalScrollbar +import net.mullvad.mullvadvpn.lib.ui.resource.R import net.mullvad.mullvadvpn.lib.ui.theme.AppTheme import net.mullvad.mullvadvpn.lib.ui.theme.Dimens import net.mullvad.mullvadvpn.lib.ui.theme.color.AlphaScrollbar -import net.mullvad.mullvadvpn.viewmodel.DeviceRevokedSideEffect -import net.mullvad.mullvadvpn.viewmodel.DeviceRevokedViewModel import org.koin.androidx.compose.koinViewModel @Preview("Secured|Unsecured|Unknown") @@ -49,9 +45,9 @@ private fun PreviewDeviceRevokedScreen( AppTheme { DeviceRevokedScreen(state = state, onSettingsClicked = {}, onGoToLoginClicked = {}) } } -@Destination<MainGraph> +@Destination<ExternalModuleGraph> @Composable -fun DeviceRevoked(navigator: DestinationsNavigator) { +fun DeviceRevoked(navController: NavController, navigator: DestinationsNavigator) { val viewModel = koinViewModel<DeviceRevokedViewModel>() val state by viewModel.uiState.collectAsStateWithLifecycle() @@ -59,9 +55,9 @@ fun DeviceRevoked(navigator: DestinationsNavigator) { CollectSideEffectWithLifecycle(viewModel.uiSideEffect) { sideEffect -> when (sideEffect) { DeviceRevokedSideEffect.NavigateToLogin -> - navigator.navigate(LoginDestination()) { + navController.navigate(LoginDestination.route) { launchSingleTop = true - popUpTo(NavGraphs.main) { inclusive = true } + popUpTo("main") { inclusive = true } } } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/DeviceRevokedUiState.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedUiState.kt index 4bc32ae757..9c42c854a6 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/DeviceRevokedUiState.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedUiState.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.state +package net.mullvad.mullvadvpn.feature.home.impl.devicerevoked enum class DeviceRevokedUiState { SECURED, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/DeviceRevokedUiStatePreviewParameterProvider.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedUiStatePreviewParameterProvider.kt index 018a160686..a5f8715f62 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/DeviceRevokedUiStatePreviewParameterProvider.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedUiStatePreviewParameterProvider.kt @@ -1,7 +1,6 @@ -package net.mullvad.mullvadvpn.compose.preview +package net.mullvad.mullvadvpn.feature.home.impl.devicerevoked import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import net.mullvad.mullvadvpn.compose.state.DeviceRevokedUiState class DeviceRevokedUiStatePreviewParameterProvider : PreviewParameterProvider<DeviceRevokedUiState> { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModel.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedViewModel.kt index 48e4322ce9..32888ec86a 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModel.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedViewModel.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.viewmodel +package net.mullvad.mullvadvpn.feature.home.impl.devicerevoked import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -10,7 +10,6 @@ import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch -import net.mullvad.mullvadvpn.compose.state.DeviceRevokedUiState import net.mullvad.mullvadvpn.lib.common.constant.VIEW_MODEL_STOP_TIMEOUT import net.mullvad.mullvadvpn.lib.pushnotification.ScheduleNotificationAlarmUseCase import net.mullvad.mullvadvpn.lib.pushnotification.accountexpiry.AccountExpiryNotificationProvider diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeScreen.kt index a69a88484f..9993c06edf 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeScreen.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.screen +package net.mullvad.mullvadvpn.feature.home.impl.outoftime import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -37,32 +37,30 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.dropUnlessResumed +import androidx.navigation.NavController import com.ramcosta.composedestinations.annotation.Destination -import com.ramcosta.composedestinations.generated.NavGraphs +import com.ramcosta.composedestinations.annotation.ExternalModuleGraph import com.ramcosta.composedestinations.generated.account.destinations.AccountDestination import com.ramcosta.composedestinations.generated.addtime.destinations.VerificationPendingDestination -import com.ramcosta.composedestinations.generated.destinations.ConnectDestination +import com.ramcosta.composedestinations.generated.home.destinations.ConnectDestination import com.ramcosta.composedestinations.generated.redeemvoucher.destinations.RedeemVoucherDestination import com.ramcosta.composedestinations.generated.settings.destinations.SettingsDestination import com.ramcosta.composedestinations.navigation.DestinationsNavigator -import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.common.compose.CollectSideEffectWithLifecycle import net.mullvad.mullvadvpn.common.compose.createOpenAccountPageHook import net.mullvad.mullvadvpn.common.compose.showSnackbarImmediately -import net.mullvad.mullvadvpn.compose.preview.OutOfTimeScreenPreviewParameterProvider -import net.mullvad.mullvadvpn.compose.state.OutOfTimeUiState -import net.mullvad.mullvadvpn.compose.transitions.HomeTransition import net.mullvad.mullvadvpn.feature.addtime.impl.AddTimeBottomSheet +import net.mullvad.mullvadvpn.feature.home.impl.HomeTransition import net.mullvad.mullvadvpn.lib.ui.component.ScaffoldWithTopBarAndDeviceName import net.mullvad.mullvadvpn.lib.ui.component.drawVerticalScrollbar import net.mullvad.mullvadvpn.lib.ui.designsystem.NegativeButton import net.mullvad.mullvadvpn.lib.ui.designsystem.VariantButton +import net.mullvad.mullvadvpn.lib.ui.resource.R import net.mullvad.mullvadvpn.lib.ui.tag.OUT_OF_TIME_SCREEN_TITLE_TEST_TAG import net.mullvad.mullvadvpn.lib.ui.tag.PLAY_PAYMENT_INFO_ICON_TEST_TAG import net.mullvad.mullvadvpn.lib.ui.theme.AppTheme import net.mullvad.mullvadvpn.lib.ui.theme.Dimens import net.mullvad.mullvadvpn.lib.ui.theme.color.AlphaScrollbar -import net.mullvad.mullvadvpn.viewmodel.OutOfTimeViewModel import org.koin.androidx.compose.koinViewModel @Preview("Disconnected|Connecting|Error") @@ -83,9 +81,9 @@ private fun PreviewOutOfTimeScreen( } } -@Destination<MainGraph>(style = HomeTransition::class) +@Destination<ExternalModuleGraph>(style = HomeTransition::class) @Composable -fun OutOfTime(navigator: DestinationsNavigator) { +fun OutOfTime(navController: NavController, navigator: DestinationsNavigator) { val vm = koinViewModel<OutOfTimeViewModel>() val state by vm.uiState.collectAsStateWithLifecycle() @@ -97,9 +95,9 @@ fun OutOfTime(navigator: DestinationsNavigator) { is OutOfTimeViewModel.UiSideEffect.OpenAccountView -> openAccountPage(uiSideEffect.token) OutOfTimeViewModel.UiSideEffect.OpenConnectScreen -> - navigator.navigate(ConnectDestination) { + navController.navigate(ConnectDestination.route) { launchSingleTop = true - popUpTo(NavGraphs.main) { inclusive = true } + popUpTo("main") { inclusive = true } } OutOfTimeViewModel.UiSideEffect.GenericError -> snackbarHostState.showSnackbarImmediately( diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/OutOfTimeScreenPreviewParameterProvider.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeScreenPreviewParameterProvider.kt index 91b05970a5..6927199ff2 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/OutOfTimeScreenPreviewParameterProvider.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeScreenPreviewParameterProvider.kt @@ -1,10 +1,9 @@ -package net.mullvad.mullvadvpn.compose.preview +package net.mullvad.mullvadvpn.feature.home.impl.outoftime import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateConnectingState -import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateDisconnectedState -import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateErrorState -import net.mullvad.mullvadvpn.compose.state.OutOfTimeUiState +import net.mullvad.mullvadvpn.feature.home.impl.TunnelStatePreviewData.generateConnectingState +import net.mullvad.mullvadvpn.feature.home.impl.TunnelStatePreviewData.generateDisconnectedState +import net.mullvad.mullvadvpn.feature.home.impl.TunnelStatePreviewData.generateErrorState class OutOfTimeScreenPreviewParameterProvider : PreviewParameterProvider<OutOfTimeUiState> { override val values: Sequence<OutOfTimeUiState> = diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/OutOfTimeUiState.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeUiState.kt index 89708d95eb..993bf60381 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/OutOfTimeUiState.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeUiState.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.state +package net.mullvad.mullvadvpn.feature.home.impl.outoftime import net.mullvad.mullvadvpn.lib.model.TunnelState diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModel.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeViewModel.kt index 79556f982b..454ca48625 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModel.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeViewModel.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.viewmodel +package net.mullvad.mullvadvpn.feature.home.impl.outoftime import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -13,7 +13,6 @@ import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch -import net.mullvad.mullvadvpn.compose.state.OutOfTimeUiState import net.mullvad.mullvadvpn.feature.addtime.impl.hasPendingPayment import net.mullvad.mullvadvpn.feature.addtime.impl.isSuccess import net.mullvad.mullvadvpn.lib.common.constant.VIEW_MODEL_STOP_TIMEOUT diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/info/DeviceNameInfoDialog.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/DeviceNameInfoDialog.kt index 9a8aad66d3..5ff3fd6dda 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/info/DeviceNameInfoDialog.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/DeviceNameInfoDialog.kt @@ -1,16 +1,16 @@ -package net.mullvad.mullvadvpn.compose.dialog.info +package net.mullvad.mullvadvpn.feature.home.impl.welcome import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import androidx.lifecycle.compose.dropUnlessResumed import com.ramcosta.composedestinations.annotation.Destination +import com.ramcosta.composedestinations.annotation.ExternalModuleGraph import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.spec.DestinationStyle -import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.compose.screen.MainGraph import net.mullvad.mullvadvpn.lib.ui.component.dialog.InfoDialog +import net.mullvad.mullvadvpn.lib.ui.resource.R -@Destination<MainGraph>(style = DestinationStyle.Dialog::class) +@Destination<ExternalModuleGraph>(style = DestinationStyle.Dialog::class) @Composable fun DeviceNameInfo(navigator: DestinationsNavigator) { InfoDialog( diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreen.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeScreen.kt index a30d159d64..38ef6721ba 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreen.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeScreen.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.screen +package net.mullvad.mullvadvpn.feature.home.impl.welcome import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -43,26 +43,24 @@ import androidx.credentials.exceptions.CreateCredentialException import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.dropUnlessResumed +import androidx.navigation.NavController import co.touchlab.kermit.Logger import com.ramcosta.composedestinations.annotation.Destination -import com.ramcosta.composedestinations.generated.NavGraphs +import com.ramcosta.composedestinations.annotation.ExternalModuleGraph import com.ramcosta.composedestinations.generated.account.destinations.AccountDestination import com.ramcosta.composedestinations.generated.addtime.destinations.VerificationPendingDestination -import com.ramcosta.composedestinations.generated.destinations.ConnectDestination -import com.ramcosta.composedestinations.generated.destinations.DeviceNameInfoDestination +import com.ramcosta.composedestinations.generated.home.destinations.ConnectDestination +import com.ramcosta.composedestinations.generated.home.destinations.DeviceNameInfoDestination import com.ramcosta.composedestinations.generated.redeemvoucher.destinations.RedeemVoucherDestination import com.ramcosta.composedestinations.generated.settings.destinations.SettingsDestination import com.ramcosta.composedestinations.navigation.DestinationsNavigator -import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.common.compose.CollectSideEffectWithLifecycle import net.mullvad.mullvadvpn.common.compose.createCopyToClipboardHandle import net.mullvad.mullvadvpn.common.compose.createOpenAccountPageHook import net.mullvad.mullvadvpn.common.compose.showSnackbarImmediately -import net.mullvad.mullvadvpn.compose.preview.WelcomeScreenUiStatePreviewParameterProvider -import net.mullvad.mullvadvpn.compose.state.WelcomeUiState -import net.mullvad.mullvadvpn.compose.transitions.HomeTransition import net.mullvad.mullvadvpn.feature.account.impl.CopyAnimatedIconButton import net.mullvad.mullvadvpn.feature.addtime.impl.AddTimeBottomSheet +import net.mullvad.mullvadvpn.feature.home.impl.HomeTransition import net.mullvad.mullvadvpn.lib.common.Lc import net.mullvad.mullvadvpn.lib.common.util.groupWithSpaces import net.mullvad.mullvadvpn.lib.ui.component.ScaffoldWithTopBar @@ -70,11 +68,11 @@ import net.mullvad.mullvadvpn.lib.ui.component.drawVerticalScrollbar import net.mullvad.mullvadvpn.lib.ui.designsystem.MullvadCircularProgressIndicatorMedium import net.mullvad.mullvadvpn.lib.ui.designsystem.NegativeButton import net.mullvad.mullvadvpn.lib.ui.designsystem.VariantButton +import net.mullvad.mullvadvpn.lib.ui.resource.R import net.mullvad.mullvadvpn.lib.ui.tag.PLAY_PAYMENT_INFO_ICON_TEST_TAG import net.mullvad.mullvadvpn.lib.ui.theme.AppTheme import net.mullvad.mullvadvpn.lib.ui.theme.Dimens import net.mullvad.mullvadvpn.lib.ui.theme.color.AlphaScrollbar -import net.mullvad.mullvadvpn.viewmodel.WelcomeViewModel import org.koin.androidx.compose.koinViewModel @Preview("Loading|Content|TunnelConnected") @@ -96,9 +94,9 @@ private fun PreviewWelcomeScreen( } } -@Destination<MainGraph>(style = HomeTransition::class) +@Destination<ExternalModuleGraph>(style = HomeTransition::class) @Composable -fun Welcome(navigator: DestinationsNavigator) { +fun Welcome(navController: NavController, navigator: DestinationsNavigator) { val vm = koinViewModel<WelcomeViewModel>() val state by vm.uiState.collectAsStateWithLifecycle() @@ -111,9 +109,9 @@ fun Welcome(navigator: DestinationsNavigator) { when (uiSideEffect) { is WelcomeViewModel.UiSideEffect.OpenAccountView -> openAccountPage(uiSideEffect.token) WelcomeViewModel.UiSideEffect.OpenConnectScreen -> - navigator.navigate(ConnectDestination) { + navController.navigate(ConnectDestination.route) { launchSingleTop = true - popUpTo(NavGraphs.main) { inclusive = true } + popUpTo("main") { inclusive = true } } WelcomeViewModel.UiSideEffect.GenericError -> snackbarHostState.showSnackbarImmediately( diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/WelcomeScreenUiStatePreviewParameterProvider.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeScreenUiStatePreviewParameterProvider.kt index 129d866daa..4f5ef3745c 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/WelcomeScreenUiStatePreviewParameterProvider.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeScreenUiStatePreviewParameterProvider.kt @@ -1,7 +1,7 @@ -package net.mullvad.mullvadvpn.compose.preview +package net.mullvad.mullvadvpn.feature.home.impl.welcome import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import net.mullvad.mullvadvpn.compose.state.WelcomeUiState +import net.mullvad.mullvadvpn.feature.home.impl.TunnelStatePreviewData import net.mullvad.mullvadvpn.lib.common.Lc import net.mullvad.mullvadvpn.lib.common.toLc import net.mullvad.mullvadvpn.lib.model.AccountNumber diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/WelcomeUiState.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeUiState.kt index 880c2b9dcf..64801e5db8 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/WelcomeUiState.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeUiState.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.compose.state +package net.mullvad.mullvadvpn.feature.home.impl.welcome import net.mullvad.mullvadvpn.lib.model.AccountNumber import net.mullvad.mullvadvpn.lib.model.TunnelState diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModel.kt b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeViewModel.kt index dd299ba6cc..9ec73dd6fe 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModel.kt +++ b/android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeViewModel.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.viewmodel +package net.mullvad.mullvadvpn.feature.home.impl.welcome import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -16,7 +16,6 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch -import net.mullvad.mullvadvpn.compose.state.WelcomeUiState import net.mullvad.mullvadvpn.feature.addtime.impl.hasPendingPayment import net.mullvad.mullvadvpn.feature.addtime.impl.isSuccess import net.mullvad.mullvadvpn.lib.common.Lc diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModelTest.kt b/android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectViewModelTest.kt index 3956056f48..c1147e9ae7 100644 --- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModelTest.kt +++ b/android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectViewModelTest.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.viewmodel +package net.mullvad.mullvadvpn.feature.home.impl.connect import androidx.lifecycle.viewModelScope import app.cash.turbine.test @@ -18,7 +18,7 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest -import net.mullvad.mullvadvpn.compose.state.ConnectUiState +import net.mullvad.mullvadvpn.feature.home.impl.connect.notificationbanner.InAppNotificationController import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule import net.mullvad.mullvadvpn.lib.model.AccountData import net.mullvad.mullvadvpn.lib.model.DeviceState @@ -37,9 +37,6 @@ import net.mullvad.mullvadvpn.lib.usecase.LastKnownLocationUseCase import net.mullvad.mullvadvpn.lib.usecase.OutOfTimeUseCase import net.mullvad.mullvadvpn.lib.usecase.SelectedLocationTitleUseCase import net.mullvad.mullvadvpn.lib.usecase.SystemVpnSettingsAvailableUseCase -import net.mullvad.mullvadvpn.repository.InAppNotificationController -import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager -import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionState import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -47,12 +44,8 @@ import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestCoroutineRule::class) class ConnectViewModelTest { - - private val mockServiceConnectionManager: ServiceConnectionManager = mockk() private lateinit var viewModel: ConnectViewModel - private val serviceConnectionState = - MutableStateFlow<ServiceConnectionState>(ServiceConnectionState.Unbound) private val accountExpiryState = MutableStateFlow<AccountData?>(null) private val device = MutableStateFlow<DeviceState?>(null) private val notifications = MutableStateFlow<List<InAppNotification>>(emptyList()) @@ -96,8 +89,6 @@ class ConnectViewModelTest { @BeforeEach fun setup() { - every { mockServiceConnectionManager.connectionState } returns serviceConnectionState - every { mockAccountRepository.accountData } returns accountExpiryState every { mockDeviceRepository.deviceState } returns device diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/InAppNotificationControllerTest.kt b/android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/notificationbanner/InAppNotificationControllerTest.kt index 3e4c0be96f..442a2fb661 100644 --- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/InAppNotificationControllerTest.kt +++ b/android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/notificationbanner/InAppNotificationControllerTest.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn +package net.mullvad.mullvadvpn.feature.home.impl.connect.notificationbanner import app.cash.turbine.test import io.mockk.MockKAnnotations @@ -21,7 +21,6 @@ import net.mullvad.mullvadvpn.lib.usecase.inappnotification.NewChangelogNotifica import net.mullvad.mullvadvpn.lib.usecase.inappnotification.NewDeviceNotificationUseCase import net.mullvad.mullvadvpn.lib.usecase.inappnotification.TunnelStateNotificationUseCase import net.mullvad.mullvadvpn.lib.usecase.inappnotification.VersionNotificationUseCase -import net.mullvad.mullvadvpn.repository.InAppNotificationController import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test diff --git a/android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/data/AccountData.kt b/android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/data/AccountData.kt new file mode 100644 index 0000000000..121ff29ee4 --- /dev/null +++ b/android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/data/AccountData.kt @@ -0,0 +1,12 @@ +package net.mullvad.mullvadvpn.feature.home.impl.data + +import io.mockk.mockk +import java.time.ZonedDateTime +import net.mullvad.mullvadvpn.lib.model.AccountData + +fun AccountData.Companion.mock(expiry: ZonedDateTime): AccountData = + AccountData( + id = mockk(relaxed = true), + accountNumber = mockk(relaxed = true), + expiryDate = expiry, + ) diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModelTest.kt b/android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedViewModelTest.kt index a56bdb8121..e06c4f42de 100644 --- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModelTest.kt +++ b/android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedViewModelTest.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.viewmodel +package net.mullvad.mullvadvpn.feature.home.impl.devicerevoked import app.cash.turbine.test import arrow.core.right @@ -13,7 +13,6 @@ import io.mockk.unmockkAll import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.test.runTest -import net.mullvad.mullvadvpn.compose.state.DeviceRevokedUiState import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule import net.mullvad.mullvadvpn.lib.model.TunnelState import net.mullvad.mullvadvpn.lib.pushnotification.ScheduleNotificationAlarmUseCase @@ -21,7 +20,7 @@ import net.mullvad.mullvadvpn.lib.pushnotification.accountexpiry.AccountExpiryNo import net.mullvad.mullvadvpn.lib.repository.AccountRepository import net.mullvad.mullvadvpn.lib.repository.ConnectionProxy import org.junit.jupiter.api.AfterEach -import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -70,9 +69,9 @@ class DeviceRevokedViewModelTest { // Act, Assert viewModel.uiState.test { - assertEquals(DeviceRevokedUiState.UNKNOWN, awaitItem()) + Assertions.assertEquals(DeviceRevokedUiState.UNKNOWN, awaitItem()) tunnelStateFlow.emit(tunnelState) - assertEquals(DeviceRevokedUiState.SECURED, awaitItem()) + Assertions.assertEquals(DeviceRevokedUiState.SECURED, awaitItem()) } } @@ -81,7 +80,7 @@ class DeviceRevokedViewModelTest { runTest { // Act, Assert viewModel.uiState.test { - assertEquals(DeviceRevokedUiState.UNKNOWN, awaitItem()) + Assertions.assertEquals(DeviceRevokedUiState.UNKNOWN, awaitItem()) coVerify { mockScheduleNotificationAlarmUseCase(null, null) } coVerify { mockAccountExpiryNotificationProvider.cancelNotification() } } diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModelTest.kt b/android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeViewModelTest.kt index 1b46f83870..85c37d6fdc 100644 --- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModelTest.kt +++ b/android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeViewModelTest.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.viewmodel +package net.mullvad.mullvadvpn.feature.home.impl.outoftime import androidx.lifecycle.viewModelScope import app.cash.turbine.test @@ -13,7 +13,6 @@ import kotlin.test.assertIs import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runTest -import net.mullvad.mullvadvpn.compose.state.OutOfTimeUiState import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule import net.mullvad.mullvadvpn.lib.model.AccountData import net.mullvad.mullvadvpn.lib.model.DeviceState @@ -30,8 +29,6 @@ import net.mullvad.mullvadvpn.lib.repository.ConnectionProxy import net.mullvad.mullvadvpn.lib.repository.DeviceRepository import net.mullvad.mullvadvpn.lib.repository.PaymentLogic import net.mullvad.mullvadvpn.lib.usecase.OutOfTimeUseCase -import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager -import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionState import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -40,8 +37,6 @@ import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestCoroutineRule::class) class OutOfTimeViewModelTest { - private val serviceConnectionStateFlow = - MutableStateFlow<ServiceConnectionState>(ServiceConnectionState.Unbound) private val accountExpiryStateFlow = MutableStateFlow<AccountData?>(null) private val accountStateFlow = MutableStateFlow<DeviceState?>(null) private val paymentAvailabilityFlow = MutableStateFlow<PaymentAvailability?>(null) @@ -56,7 +51,6 @@ class OutOfTimeViewModelTest { private val mockAccountRepository: AccountRepository = mockk(relaxed = true) private val mockDeviceRepository: DeviceRepository = mockk(relaxed = true) - private val mockServiceConnectionManager: ServiceConnectionManager = mockk() private val mockPaymentUseCase: PaymentLogic = mockk(relaxed = true) private val mockOutOfTimeUseCase: OutOfTimeUseCase = mockk(relaxed = true) @@ -64,8 +58,6 @@ class OutOfTimeViewModelTest { @BeforeEach fun setup() { - every { mockServiceConnectionManager.connectionState } returns serviceConnectionStateFlow - every { mockConnectionProxy.tunnelState } returns tunnelState every { mockAccountRepository.accountData } returns accountExpiryStateFlow @@ -99,7 +91,7 @@ class OutOfTimeViewModelTest { @Test fun `when clicking on site payment then open website account view`() = runTest { // Arrange - val mockToken = WebsiteAuthToken.fromString("154c4cc94810fddac78398662b7fa0c7") + val mockToken = WebsiteAuthToken.Companion.fromString("154c4cc94810fddac78398662b7fa0c7") coEvery { mockAccountRepository.getWebsiteAuthToken() } returns mockToken // Act, Assert diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModelTest.kt b/android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeViewModelTest.kt index 48361180bd..44f4c84550 100644 --- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModelTest.kt +++ b/android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeViewModelTest.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.viewmodel +package net.mullvad.mullvadvpn.feature.home.impl.welcome import androidx.lifecycle.viewModelScope import app.cash.turbine.test @@ -14,8 +14,7 @@ import kotlin.test.assertIs import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runTest -import net.mullvad.mullvadvpn.compose.state.WelcomeUiState -import net.mullvad.mullvadvpn.data.mock +import net.mullvad.mullvadvpn.feature.home.impl.data.mock import net.mullvad.mullvadvpn.lib.common.Lc import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule import net.mullvad.mullvadvpn.lib.model.AccountData @@ -34,8 +33,6 @@ import net.mullvad.mullvadvpn.lib.repository.AccountRepository import net.mullvad.mullvadvpn.lib.repository.ConnectionProxy import net.mullvad.mullvadvpn.lib.repository.DeviceRepository import net.mullvad.mullvadvpn.lib.repository.PaymentLogic -import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager -import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionState import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -44,8 +41,6 @@ import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestCoroutineRule::class) class WelcomeViewModelTest { - private val serviceConnectionStateFlow = - MutableStateFlow<ServiceConnectionState>(ServiceConnectionState.Unbound) private val deviceStateFlow = MutableStateFlow<DeviceState?>(DeviceState.LoggedOut) private val accountExpiryStateFlow = MutableStateFlow<AccountData?>(null) private val purchaseResultFlow = MutableStateFlow<PurchaseResult?>(null) @@ -59,7 +54,6 @@ class WelcomeViewModelTest { private val mockAccountRepository: AccountRepository = mockk(relaxed = true) private val mockDeviceRepository: DeviceRepository = mockk(relaxed = true) - private val mockServiceConnectionManager: ServiceConnectionManager = mockk() private val mockPaymentUseCase: PaymentLogic = mockk(relaxed = true) private lateinit var viewModel: WelcomeViewModel @@ -68,8 +62,6 @@ class WelcomeViewModelTest { fun setup() { every { mockDeviceRepository.deviceState } returns deviceStateFlow - every { mockServiceConnectionManager.connectionState } returns serviceConnectionStateFlow - every { mockConnectionProxy.tunnelState } returns tunnelState every { mockAccountRepository.accountData } returns accountExpiryStateFlow @@ -98,7 +90,7 @@ class WelcomeViewModelTest { @Test fun `on onSitePaymentClick call uiSideEffect should emit OpenAccountView`() = runTest { // Arrange - val mockToken = WebsiteAuthToken.fromString("154c4cc94810fddac78398662b7fa0c7") + val mockToken = WebsiteAuthToken.Companion.fromString("154c4cc94810fddac78398662b7fa0c7") coEvery { mockAccountRepository.getWebsiteAuthToken() } returns mockToken // Act, Assert diff --git a/android/lib/feature/login/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/login/impl/LoginScreen.kt b/android/lib/feature/login/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/login/impl/LoginScreen.kt index 690176e1d0..35f0fb21f2 100644 --- a/android/lib/feature/login/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/login/impl/LoginScreen.kt +++ b/android/lib/feature/login/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/login/impl/LoginScreen.kt @@ -62,6 +62,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.LayoutDirection import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.dropUnlessResumed +import androidx.navigation.NavController import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.ExternalModuleGraph import com.ramcosta.composedestinations.generated.login.destinations.ApiUnreachableInfoDestination @@ -121,6 +122,7 @@ private const val BOTTOM_SPACER_WEIGHT = 3f @Destination<ExternalModuleGraph>(style = LoginTransition::class) @Composable fun Login( + navController: NavController, navigator: DestinationsNavigator, accountNumber: String? = null, vm: LoginViewModel = koinViewModel(), @@ -164,28 +166,25 @@ fun Login( CollectSideEffectWithLifecycle(vm.uiSideEffect) { when (it) { - LoginUiSideEffect.NavigateToWelcome -> {} - // TODO How to solve this? - // navigator.navigate(WelcomeDestination) { - // launchSingleTop = true - // popUpTo(NavGraphs.main) { inclusive = true } - // } - is LoginUiSideEffect.NavigateToConnect -> {} - // TODO How to solve this? - // navigator.navigate(ConnectDestination) { - // launchSingleTop = true - // popUpTo(NavGraphs.main) { inclusive = true } - // } + LoginUiSideEffect.NavigateToWelcome -> + navController.navigate("home/welcome") { + launchSingleTop = true + popUpTo("main") { inclusive = true } + } + is LoginUiSideEffect.NavigateToConnect -> + navController.navigate("home/connect") { + launchSingleTop = true + popUpTo("main") { inclusive = true } + } is LoginUiSideEffect.TooManyDevices -> navigator.navigate(DeviceListDestination(it.accountNumber)) { launchSingleTop = true } - LoginUiSideEffect.NavigateToOutOfTime -> {} - // TODO How to solve this? - // navigator.navigate(OutOfTimeDestination) { - // launchSingleTop = true - // popUpTo(NavGraphs.main) { inclusive = true } - // } + LoginUiSideEffect.NavigateToOutOfTime -> + navController.navigate("home/out_of_time") { + launchSingleTop = true + popUpTo("main") { inclusive = true } + } LoginUiSideEffect.NavigateToCreateAccountConfirmation -> navigator.navigate(CreateAccountConfirmationDestination) LoginUiSideEffect.GenericError -> diff --git a/android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/Navigation.kt b/android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/Navigation.kt index ab94081b7f..ab94081b7f 100644 --- a/android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/Navigation.kt +++ b/android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/Navigation.kt diff --git a/android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/AccountTransition.kt b/android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/AccountTransition.kt index e4fa8e72f8..e4fa8e72f8 100644 --- a/android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/AccountTransition.kt +++ b/android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/AccountTransition.kt diff --git a/android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/AnimationConstant.kt b/android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/AnimationConstant.kt index 12eb6e2215..12eb6e2215 100644 --- a/android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/AnimationConstant.kt +++ b/android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/AnimationConstant.kt diff --git a/android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/DefaultTransition.kt b/android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/DefaultTransition.kt index cc45ab55fe..cc45ab55fe 100644 --- a/android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/DefaultTransition.kt +++ b/android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/DefaultTransition.kt diff --git a/android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/LoginTransition.kt b/android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/LoginTransition.kt index b43594752a..863ee93916 100644 --- a/android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/LoginTransition.kt +++ b/android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/LoginTransition.kt @@ -19,15 +19,13 @@ object LoginTransition : DestinationStyle.Animated() { override val exitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition = { - // TODO How to solve this? - fadeOut(spring()) - // when (this.targetState.destination()) { - // is OutOfTimeDestination, - // is WelcomeDestination, - // is ConnectDestination, - // is DeviceListDestination -> fadeOut(spring()) - // else -> ExitTransition.None - // } + when (this.targetState.destination.route) { + "home/out_of_time", + "home/welcome", + "home/connect", + "login/device_list" -> fadeOut(spring()) + else -> ExitTransition.None + } } override val popEnterTransition: diff --git a/android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/SlideInFromRightTransition.kt b/android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/SlideInFromRightTransition.kt index 79587f47c2..79587f47c2 100644 --- a/android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/SlideInFromRightTransition.kt +++ b/android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/SlideInFromRightTransition.kt diff --git a/android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/TopLevelTransition.kt b/android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/TopLevelTransition.kt index 3297be9627..3297be9627 100644 --- a/android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/TopLevelTransition.kt +++ b/android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/TopLevelTransition.kt diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts index 81742fef9a..ad72b41b40 100644 --- a/android/settings.gradle.kts +++ b/android/settings.gradle.kts @@ -48,6 +48,7 @@ include( ":lib:feature:customlist:impl", ":lib:feature:daita:impl", ":lib:feature:filter:impl", + ":lib:feature:home:impl", ":lib:feature:login:impl", ":lib:feature:managedevices:impl", ":lib:feature:multihop:impl", |
