summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJonatan Rhodin <jonatan.rhodin@mullvad.net>2026-02-13 10:22:53 +0100
committerJonatan Rhodin <jonatan.rhodin@mullvad.net>2026-02-13 10:51:48 +0100
commita9a169c0222d741056dfbb4d98dbe8de77e2d002 (patch)
treec13eaa97507976bb3f80d90f46794a448bdaec65
parentf03d6437ca6070407a2adbb1e50e6ba761e0c429 (diff)
downloadmullvadvpn-a9a169c0222d741056dfbb4d98dbe8de77e2d002.tar.xz
mullvadvpn-a9a169c0222d741056dfbb4d98dbe8de77e2d002.zip
Refactor connect into feature module
-rw-r--r--android/app/build.gradle.kts1
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ExternalActionButton.kt74
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/MullvadSegmentedButton.kt121
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/SelectObfuscationCellPreviewParameterProvider.kt23
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/ShadowsocksSettingsUiStatePreviewParameterProvider.kt18
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MullvadApp.kt20
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplashScreen.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/ConnectNotificationState.kt1
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/ShadowsocksSettingsUiState.kt11
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/util/Navigation.kt17
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt10
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt2
-rw-r--r--android/lib/common-compose/src/main/kotlin/net/mullvad/mullvadvpn/common/compose/Shared.kt10
-rw-r--r--android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/CreateVpnProfile.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/util/CreateVpnProfile.kt)2
-rw-r--r--android/lib/feature/account/impl/build.gradle.kts1
-rw-r--r--android/lib/feature/account/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/account/impl/AccountScreen.kt11
-rw-r--r--android/lib/feature/home/impl/build.gradle.kts50
-rw-r--r--android/lib/feature/home/impl/src/androidTest/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectScreenTest.kt (renamed from android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt)3
-rw-r--r--android/lib/feature/home/impl/src/androidTest/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedScreenTest.kt (renamed from android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreenTest.kt)3
-rw-r--r--android/lib/feature/home/impl/src/androidTest/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeScreenTest.kt (renamed from android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreenTest.kt)3
-rw-r--r--android/lib/feature/home/impl/src/androidTest/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeScreenTest.kt (renamed from android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreenTest.kt)3
-rw-r--r--android/lib/feature/home/impl/src/main/AndroidManifest.xml4
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/HomeTransition.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/transitions/HomeTransition.kt)6
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/TunnelStatePreviewData.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/TunnelStatePreviewData.kt)2
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/Android16UpgradeWarningInfoDialog.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/info/Android16UpgradeWarningInfoDialog.kt)8
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectScreen.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt)61
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectUiState.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/ConnectUiState.kt)2
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectUiStatePreviewParameterProvider.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/ConnectUiStatePreviewParameterProvider.kt)4
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectViewModel.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt)9
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectionStatusText.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt)5
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/TunnelStatePreviewParameterProvider.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/TunnelStatePreviewParameterProvider.kt)12
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/button/ConnectionButton.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt)6
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/button/SwitchLocationButton.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/SwitchLocationButton.kt)6
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/connectioninfo/ConnectionDetailPanel.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/connectioninfo/ConnectionDetailPanel.kt)12
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/connectioninfo/ConnectionInfoHeader.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/connectioninfo/ConnectionInfoHeader.kt)2
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/connectioninfo/FeatureIndicatorsPanel.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/connectioninfo/FeatureIndicatorsPanel.kt)8
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/notificationbanner/InAppNotificationController.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/InAppNotificationController.kt)4
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/notificationbanner/NotificationBanner.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/notificationbanner/NotificationBanner.kt)2
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedLoginButton.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/DeviceRevokedLoginButton.kt)5
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedScreen.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreen.kt)20
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedUiState.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/DeviceRevokedUiState.kt)2
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedUiStatePreviewParameterProvider.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/DeviceRevokedUiStatePreviewParameterProvider.kt)3
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedViewModel.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModel.kt)3
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeScreen.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt)22
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeScreenPreviewParameterProvider.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/OutOfTimeScreenPreviewParameterProvider.kt)9
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeUiState.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/OutOfTimeUiState.kt)2
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeViewModel.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModel.kt)3
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/DeviceNameInfoDialog.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/info/DeviceNameInfoDialog.kt)8
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeScreen.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreen.kt)24
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeScreenUiStatePreviewParameterProvider.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/WelcomeScreenUiStatePreviewParameterProvider.kt)4
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeUiState.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/WelcomeUiState.kt)2
-rw-r--r--android/lib/feature/home/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeViewModel.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModel.kt)3
-rw-r--r--android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/ConnectViewModelTest.kt (renamed from android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModelTest.kt)13
-rw-r--r--android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/connect/notificationbanner/InAppNotificationControllerTest.kt (renamed from android/app/src/test/kotlin/net/mullvad/mullvadvpn/InAppNotificationControllerTest.kt)3
-rw-r--r--android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/data/AccountData.kt12
-rw-r--r--android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/devicerevoked/DeviceRevokedViewModelTest.kt (renamed from android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModelTest.kt)11
-rw-r--r--android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/outoftime/OutOfTimeViewModelTest.kt (renamed from android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModelTest.kt)12
-rw-r--r--android/lib/feature/home/impl/src/test/kotlin/net/mullvad/mullvadvpn/feature/home/impl/welcome/WelcomeViewModelTest.kt (renamed from android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModelTest.kt)14
-rw-r--r--android/lib/feature/login/impl/src/main/kotlin/net/mullvad/mullvadvpn/feature/login/impl/LoginScreen.kt35
-rw-r--r--android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/Navigation.kt (renamed from android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/Navigation.kt)0
-rw-r--r--android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/AccountTransition.kt (renamed from android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/AccountTransition.kt)0
-rw-r--r--android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/AnimationConstant.kt (renamed from android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/AnimationConstant.kt)0
-rw-r--r--android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/DefaultTransition.kt (renamed from android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/DefaultTransition.kt)0
-rw-r--r--android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/LoginTransition.kt (renamed from android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/LoginTransition.kt)16
-rw-r--r--android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/SlideInFromRightTransition.kt (renamed from android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/SlideInFromRightTransition.kt)0
-rw-r--r--android/lib/navigation/src/main/kotlin/net/mullvad/mullvadvpn/core/animation/TopLevelTransition.kt (renamed from android/lib/navigation/src/main/java/net/mullvad/mullvadvpn/core/animation/TopLevelTransition.kt)0
-rw-r--r--android/settings.gradle.kts1
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",