summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Göransson <david.goransson@mullvad.net>2026-02-11 09:37:36 +0100
committerDavid Göransson <david.goransson@mullvad.net>2026-02-11 09:37:36 +0100
commitf6d3a51138598890542fc1801f1765723460c4a3 (patch)
tree753419ab8a6f13c24fd2a2880594ce4fa7f7b63e
parent6b260ee344c82d646152321c3b77e4acd43ade76 (diff)
parent7b09a245e60804a550fc96467b54aaabb1d16d16 (diff)
downloadmullvadvpn-ios-bug-bash-02-11.tar.xz
mullvadvpn-ios-bug-bash-02-11.zip
Merge branch 'refactor-customlist-into-module'ios-bug-bash-02-11
-rw-r--r--android/app/build.gradle.kts1
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/constant/CommonContentKey.kt7
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MullvadApp.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreen.kt8
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreen.kt10
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt12
-rw-r--r--android/lib/feature/customlist/impl/build.gradle.kts26
-rw-r--r--android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/CreateCustomListDialogTest.kt (renamed from android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialogTest.kt)5
-rw-r--r--android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/CustomListLocationsScreenTest.kt (renamed from android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreenTest.kt)11
-rw-r--r--android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/CustomListsScreenTest.kt (renamed from android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreenTest.kt)7
-rw-r--r--android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/DeleteCustomListConfirmationDialogTest.kt (renamed from android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialogTest.kt)5
-rw-r--r--android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/EditCustomListNameDialogTest.kt (renamed from android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialogTest.kt)5
-rw-r--r--android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/EditCustomListScreenTest.kt (renamed from android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreenTest.kt)8
-rw-r--r--android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/data/DummyRelayItems.kt248
-rw-r--r--android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/util/Keyboard.kt (renamed from android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/util/Keyboard.kt)2
-rw-r--r--android/lib/feature/customlist/impl/src/main/AndroidManifest.xml4
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/component/CustomListNameTextField.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/CustomListNameTextField.kt)2
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/create/CreateCustomListDialog.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialog.kt)15
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/create/CreateCustomListDialogViewModel.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/CreateCustomListDialogViewModel.kt)5
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/create/CreateCustomListUiState.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/CreateCustomListUiState.kt)2
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/delete/DeleteCustomListConfirmationDialog.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialog.kt)11
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/delete/DeleteCustomListConfirmationViewModel.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeleteCustomListConfirmationViewModel.kt)5
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/delete/DeleteCustomListUiState.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/DeleteCustomListUiState.kt)2
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/discard/DiscardChangesDialog.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DiscardChangesDialog.kt)8
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlist/EditCustomListScreen.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreen.kt)16
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlist/EditCustomListUiState.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/EditCustomListUiState.kt)2
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlist/EditCustomListUiStatePreviewParameterProvider.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/EditCustomListUiStatePreviewParameterProvider.kt)3
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlist/EditCustomListViewModel.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/EditCustomListViewModel.kt)5
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/ContentKey.kt6
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/CustomListLocationUiStatePreviewParameterProvider.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/CustomListLocationUiStatePreviewParameterProvider.kt)4
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/CustomListLocationsScreen.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreen.kt)39
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/CustomListLocationsUiState.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/CustomListLocationsUiState.kt)2
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/CustomListLocationsViewModel.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListLocationsViewModel.kt)6
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/EmptyRelayListText.kt31
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/SearchTextField.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/SearchTextField.kt)4
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editname/EditCustomListNameDialog.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialog.kt)13
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editname/EditCustomListNameDialogViewModel.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/EditCustomListNameDialogViewModel.kt)5
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editname/EditCustomListNameUiState.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/EditCustomListNameUiState.kt)2
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/lists/CustomListsScreen.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreen.kt)21
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/lists/CustomListsUiState.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/CustomListsUiState.kt)2
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/lists/CustomListsUiStatePreviewParameterProvider.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/CustomListsUiStatePreviewParameterProvider.kt)3
-rw-r--r--android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/lists/CustomListsViewModel.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListsViewModel.kt)3
-rw-r--r--android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/CreateCustomListDialogViewModelTest.kt (renamed from android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/CreateCustomListDialogViewModelTest.kt)8
-rw-r--r--android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/CustomListLocationsViewModelTest.kt (renamed from android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListLocationsViewModelTest.kt)12
-rw-r--r--android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/CustomListsViewModelTest.kt (renamed from android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListsViewModelTest.kt)5
-rw-r--r--android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/DeleteCustomListConfirmationViewModelTest.kt (renamed from android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/DeleteCustomListConfirmationViewModelTest.kt)8
-rw-r--r--android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/EditCustomListNameDialogViewModelTest.kt (renamed from android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/EditCustomListNameDialogViewModelTest.kt)8
-rw-r--r--android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/EditCustomListViewModelTest.kt (renamed from android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/EditCustomListViewModelTest.kt)9
-rw-r--r--android/settings.gradle.kts1
49 files changed, 480 insertions, 159 deletions
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts
index 5f992a994d..fa4ddc899a 100644
--- a/android/app/build.gradle.kts
+++ b/android/app/build.gradle.kts
@@ -391,6 +391,7 @@ dependencies {
implementation(projects.lib.feature.apiaccess.impl)
implementation(projects.lib.feature.appinfo.impl)
implementation(projects.lib.feature.appearance.impl)
+ implementation(projects.lib.feature.customlist.impl)
implementation(projects.lib.feature.daita.impl)
implementation(projects.lib.feature.filter.impl)
implementation(projects.lib.feature.multihop.impl)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/constant/CommonContentKey.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/constant/CommonContentKey.kt
deleted file mode 100644
index 899a5b8fee..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/constant/CommonContentKey.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package net.mullvad.mullvadvpn.compose.constant
-
-object CommonContentKey {
- const val DESCRIPTION = "description"
- const val PROGRESS = "progress"
- const val EMPTY = "empty"
-}
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 d13206d255..2acee39488 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
@@ -34,6 +34,12 @@ import com.ramcosta.composedestinations.generated.apiaccess.destinations.SaveApi
import com.ramcosta.composedestinations.generated.appearance.destinations.AppearanceDestination
import com.ramcosta.composedestinations.generated.appinfo.destinations.AppInfoDestination
import com.ramcosta.composedestinations.generated.appinfo.destinations.ChangelogDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.CreateCustomListDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.CustomListLocationsDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.CustomListsDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.DeleteCustomListDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.DiscardChangesDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.EditCustomListDestination
import com.ramcosta.composedestinations.generated.daita.destinations.DaitaDestination
import com.ramcosta.composedestinations.generated.daita.destinations.DaitaDirectOnlyConfirmationDestination
import com.ramcosta.composedestinations.generated.daita.destinations.DaitaDirectOnlyInfoDestination
@@ -68,13 +74,19 @@ annotation class MainGraph {
@ExternalDestination<AppInfoDestination>
@ExternalDestination<AppearanceDestination>
@ExternalDestination<ChangelogDestination>
+ @ExternalDestination<CreateCustomListDestination>
+ @ExternalDestination<CustomListLocationsDestination>
+ @ExternalDestination<CustomListsDestination>
@ExternalDestination<CustomPortDestination>
@ExternalDestination<DaitaDestination>
@ExternalDestination<DaitaDirectOnlyConfirmationDestination>
@ExternalDestination<DaitaDirectOnlyInfoDestination>
@ExternalDestination<DeleteApiAccessMethodConfirmationDestination>
+ @ExternalDestination<DeleteCustomListDestination>
@ExternalDestination<DiscardApiAccessChangesDestination>
+ @ExternalDestination<DiscardChangesDestination>
@ExternalDestination<EditApiAccessMethodDestination>
+ @ExternalDestination<EditCustomListDestination>
@ExternalDestination<EncryptedDnsProxyInfoDestination>
@ExternalDestination<FilterDestination>
@ExternalDestination<ImportOverridesByTextDestination>
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreen.kt
index d2a789d3af..7f609811dd 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreen.kt
@@ -44,10 +44,10 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.compose.dropUnlessResumed
import com.ramcosta.composedestinations.annotation.Destination
-import com.ramcosta.composedestinations.generated.destinations.CreateCustomListDestination
-import com.ramcosta.composedestinations.generated.destinations.CustomListLocationsDestination
-import com.ramcosta.composedestinations.generated.destinations.DeleteCustomListDestination
-import com.ramcosta.composedestinations.generated.destinations.EditCustomListNameDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.CreateCustomListDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.CustomListLocationsDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.DeleteCustomListDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.EditCustomListNameDestination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.result.ResultBackNavigator
import com.ramcosta.composedestinations.result.ResultRecipient
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreen.kt
index 7a1ccc4b5c..5eddf7b054 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreen.kt
@@ -69,12 +69,12 @@ import androidx.constraintlayout.compose.layoutId
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.compose.dropUnlessResumed
import com.ramcosta.composedestinations.annotation.Destination
+import com.ramcosta.composedestinations.generated.customlist.destinations.CreateCustomListDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.CustomListLocationsDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.CustomListsDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.DeleteCustomListDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.EditCustomListNameDestination
import com.ramcosta.composedestinations.generated.daita.destinations.DaitaDestination
-import com.ramcosta.composedestinations.generated.destinations.CreateCustomListDestination
-import com.ramcosta.composedestinations.generated.destinations.CustomListLocationsDestination
-import com.ramcosta.composedestinations.generated.destinations.CustomListsDestination
-import com.ramcosta.composedestinations.generated.destinations.DeleteCustomListDestination
-import com.ramcosta.composedestinations.generated.destinations.EditCustomListNameDestination
import com.ramcosta.composedestinations.generated.destinations.SearchLocationDestination
import com.ramcosta.composedestinations.generated.filter.destinations.FilterDestination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
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 915c657aa1..22acd70f3d 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
@@ -21,6 +21,12 @@ import net.mullvad.mullvadvpn.compose.screen.location.RelayListScrollConnection
import net.mullvad.mullvadvpn.compose.util.BackstackObserver
import net.mullvad.mullvadvpn.constant.IS_FDROID_BUILD
import net.mullvad.mullvadvpn.constant.IS_PLAY_BUILD
+import net.mullvad.mullvadvpn.customlist.impl.screen.create.CreateCustomListDialogViewModel
+import net.mullvad.mullvadvpn.customlist.impl.screen.delete.DeleteCustomListConfirmationViewModel
+import net.mullvad.mullvadvpn.customlist.impl.screen.editlist.EditCustomListViewModel
+import net.mullvad.mullvadvpn.customlist.impl.screen.editlocations.CustomListLocationsViewModel
+import net.mullvad.mullvadvpn.customlist.impl.screen.editname.EditCustomListNameDialogViewModel
+import net.mullvad.mullvadvpn.customlist.impl.screen.lists.CustomListsViewModel
import net.mullvad.mullvadvpn.feature.daita.impl.DaitaViewModel
import net.mullvad.mullvadvpn.feature.splittunneling.impl.SplitTunnelingViewModel
import net.mullvad.mullvadvpn.feature.splittunneling.impl.applist.ApplicationsProvider
@@ -86,15 +92,9 @@ import net.mullvad.mullvadvpn.viewmodel.AccountViewModel
import net.mullvad.mullvadvpn.viewmodel.AddTimeViewModel
import net.mullvad.mullvadvpn.viewmodel.ApiUnreachableViewModel
import net.mullvad.mullvadvpn.viewmodel.ConnectViewModel
-import net.mullvad.mullvadvpn.viewmodel.CreateCustomListDialogViewModel
-import net.mullvad.mullvadvpn.viewmodel.CustomListLocationsViewModel
-import net.mullvad.mullvadvpn.viewmodel.CustomListsViewModel
-import net.mullvad.mullvadvpn.viewmodel.DeleteCustomListConfirmationViewModel
import net.mullvad.mullvadvpn.viewmodel.DeviceListViewModel
import net.mullvad.mullvadvpn.viewmodel.DeviceRevokedViewModel
import net.mullvad.mullvadvpn.viewmodel.DnsDialogViewModel
-import net.mullvad.mullvadvpn.viewmodel.EditCustomListNameDialogViewModel
-import net.mullvad.mullvadvpn.viewmodel.EditCustomListViewModel
import net.mullvad.mullvadvpn.viewmodel.LoginViewModel
import net.mullvad.mullvadvpn.viewmodel.ManageDevicesViewModel
import net.mullvad.mullvadvpn.viewmodel.MtuDialogViewModel
diff --git a/android/lib/feature/customlist/impl/build.gradle.kts b/android/lib/feature/customlist/impl/build.gradle.kts
new file mode 100644
index 0000000000..82a475ca8f
--- /dev/null
+++ b/android/lib/feature/customlist/impl/build.gradle.kts
@@ -0,0 +1,26 @@
+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.customlist.impl"
+ ksp { arg("compose-destinations.moduleName", "customlist") }
+}
+
+dependencies {
+ implementation(projects.lib.repository)
+ implementation(projects.lib.usecase)
+ implementation(projects.lib.navigation)
+
+ implementation(libs.koin.compose)
+ implementation(libs.arrow)
+
+ // Destinations
+ implementation(libs.compose.destinations)
+ ksp(libs.compose.destinations.ksp)
+}
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialogTest.kt b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/CreateCustomListDialogTest.kt
index 3431f6d5bc..4072a28dd2 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialogTest.kt
+++ b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/CreateCustomListDialogTest.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.dialog
+package net.mullvad.mullvadvpn.customlist.impl
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithTag
@@ -9,7 +9,8 @@ import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
-import net.mullvad.mullvadvpn.compose.state.CreateCustomListUiState
+import net.mullvad.mullvadvpn.customlist.impl.screen.create.CreateCustomListDialog
+import net.mullvad.mullvadvpn.customlist.impl.screen.create.CreateCustomListUiState
import net.mullvad.mullvadvpn.lib.model.CustomListAlreadyExists
import net.mullvad.mullvadvpn.lib.model.UnknownCustomListError
import net.mullvad.mullvadvpn.lib.ui.tag.CREATE_CUSTOM_LIST_DIALOG_INPUT_TEST_TAG
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreenTest.kt b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/CustomListLocationsScreenTest.kt
index 71aa56fc63..96c9beaac4 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreenTest.kt
+++ b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/CustomListLocationsScreenTest.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.screen
+package net.mullvad.mullvadvpn.customlist.impl
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithTag
@@ -9,10 +9,11 @@ import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
-import net.mullvad.mullvadvpn.compose.data.DUMMY_RELAY_COUNTRIES
-import net.mullvad.mullvadvpn.compose.state.CustomListLocationsData
-import net.mullvad.mullvadvpn.compose.state.CustomListLocationsUiState
-import net.mullvad.mullvadvpn.compose.util.DisableSoftKeyboard
+import net.mullvad.mullvadvpn.customlist.impl.data.DUMMY_RELAY_COUNTRIES
+import net.mullvad.mullvadvpn.customlist.impl.screen.editlocations.CustomListLocationsData
+import net.mullvad.mullvadvpn.customlist.impl.screen.editlocations.CustomListLocationsScreen
+import net.mullvad.mullvadvpn.customlist.impl.screen.editlocations.CustomListLocationsUiState
+import net.mullvad.mullvadvpn.customlist.impl.util.DisableSoftKeyboard
import net.mullvad.mullvadvpn.lib.common.Lce
import net.mullvad.mullvadvpn.lib.model.RelayItem
import net.mullvad.mullvadvpn.lib.ui.component.relaylist.CheckableRelayListItem
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreenTest.kt b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/CustomListsScreenTest.kt
index 5e37903ae1..f3f6afaac2 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreenTest.kt
+++ b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/CustomListsScreenTest.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.screen
+package net.mullvad.mullvadvpn.customlist.impl
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithTag
@@ -8,8 +8,9 @@ import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
-import net.mullvad.mullvadvpn.compose.data.DUMMY_CUSTOM_LISTS
-import net.mullvad.mullvadvpn.compose.state.CustomListsUiState
+import net.mullvad.mullvadvpn.customlist.impl.data.DUMMY_CUSTOM_LISTS
+import net.mullvad.mullvadvpn.customlist.impl.screen.lists.CustomListsScreen
+import net.mullvad.mullvadvpn.customlist.impl.screen.lists.CustomListsUiState
import net.mullvad.mullvadvpn.lib.model.CustomList
import net.mullvad.mullvadvpn.lib.ui.tag.CIRCULAR_PROGRESS_INDICATOR_TEST_TAG
import net.mullvad.mullvadvpn.lib.ui.tag.NEW_LIST_BUTTON_TEST_TAG
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialogTest.kt b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/DeleteCustomListConfirmationDialogTest.kt
index f5228a95cf..67eb6870ea 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialogTest.kt
+++ b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/DeleteCustomListConfirmationDialogTest.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.dialog
+package net.mullvad.mullvadvpn.customlist.impl
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithText
@@ -7,7 +7,8 @@ import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
-import net.mullvad.mullvadvpn.compose.state.DeleteCustomListUiState
+import net.mullvad.mullvadvpn.customlist.impl.screen.delete.DeleteCustomListConfirmationDialog
+import net.mullvad.mullvadvpn.customlist.impl.screen.delete.DeleteCustomListUiState
import net.mullvad.mullvadvpn.lib.model.CustomListName
import net.mullvad.mullvadvpn.screen.test.createEdgeToEdgeComposeExtension
import net.mullvad.mullvadvpn.screen.test.setContentWithTheme
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialogTest.kt b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/EditCustomListNameDialogTest.kt
index 2836466f15..e43d83d6f8 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialogTest.kt
+++ b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/EditCustomListNameDialogTest.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.dialog
+package net.mullvad.mullvadvpn.customlist.impl
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithTag
@@ -9,7 +9,8 @@ import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
-import net.mullvad.mullvadvpn.compose.state.EditCustomListNameUiState
+import net.mullvad.mullvadvpn.customlist.impl.screen.editname.EditCustomListNameDialog
+import net.mullvad.mullvadvpn.customlist.impl.screen.editname.EditCustomListNameUiState
import net.mullvad.mullvadvpn.lib.model.CustomListName
import net.mullvad.mullvadvpn.lib.model.NameAlreadyExists
import net.mullvad.mullvadvpn.lib.model.UnknownCustomListError
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreenTest.kt b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/EditCustomListScreenTest.kt
index d7cd2e94d1..e8d30c241d 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreenTest.kt
+++ b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/EditCustomListScreenTest.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.screen
+package net.mullvad.mullvadvpn.customlist.impl
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithTag
@@ -8,8 +8,10 @@ import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
-import net.mullvad.mullvadvpn.compose.data.DUMMY_CUSTOM_LISTS
-import net.mullvad.mullvadvpn.compose.state.EditCustomListUiState
+import kotlin.text.format
+import net.mullvad.mullvadvpn.customlist.impl.data.DUMMY_CUSTOM_LISTS
+import net.mullvad.mullvadvpn.customlist.impl.screen.editlist.EditCustomListScreen
+import net.mullvad.mullvadvpn.customlist.impl.screen.editlist.EditCustomListUiState
import net.mullvad.mullvadvpn.lib.model.CustomListId
import net.mullvad.mullvadvpn.lib.model.CustomListName
import net.mullvad.mullvadvpn.lib.ui.tag.CIRCULAR_PROGRESS_INDICATOR_TEST_TAG
diff --git a/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/data/DummyRelayItems.kt b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/data/DummyRelayItems.kt
new file mode 100644
index 0000000000..a26d52f8dc
--- /dev/null
+++ b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/data/DummyRelayItems.kt
@@ -0,0 +1,248 @@
+package net.mullvad.mullvadvpn.customlist.impl.data
+
+import net.mullvad.mullvadvpn.lib.model.GeoLocationId
+import net.mullvad.mullvadvpn.lib.model.Ownership
+import net.mullvad.mullvadvpn.lib.model.ProviderId
+import net.mullvad.mullvadvpn.lib.model.Quic
+import net.mullvad.mullvadvpn.lib.model.RelayItem
+
+private val DUMMY_RELAY_1 =
+ RelayItem.Location.Relay(
+ id =
+ GeoLocationId.Hostname(
+ city = GeoLocationId.City(GeoLocationId.Country("RCo1"), "Relay City 1"),
+ "Relay host 1",
+ ),
+ active = true,
+ provider = ProviderId("PROVIDER RENTED"),
+ ownership = Ownership.Rented,
+ daita = false,
+ quic = null,
+ lwo = false,
+ )
+private val DUMMY_RELAY_2 =
+ RelayItem.Location.Relay(
+ id =
+ GeoLocationId.Hostname(
+ city = GeoLocationId.City(GeoLocationId.Country("RCo2"), "Relay City 2"),
+ "Relay host 2",
+ ),
+ active = true,
+ provider = ProviderId("PROVIDER OWNED"),
+ ownership = Ownership.MullvadOwned,
+ daita = false,
+ quic = null,
+ lwo = false,
+ )
+private val DUMMY_RELAY_3 =
+ RelayItem.Location.Relay(
+ id =
+ GeoLocationId.Hostname(
+ city = GeoLocationId.City(GeoLocationId.Country("RCo3"), "Relay City 3"),
+ "Relay host 3",
+ ),
+ active = true,
+ provider = ProviderId("PROVIDER OWNED"),
+ ownership = Ownership.MullvadOwned,
+ daita = true,
+ quic = null,
+ lwo = true,
+ )
+private val DUMMY_RELAY_4 =
+ RelayItem.Location.Relay(
+ id =
+ GeoLocationId.Hostname(
+ city = GeoLocationId.City(GeoLocationId.Country("RCo4"), "Relay City 4"),
+ "Relay host 4",
+ ),
+ active = true,
+ provider = ProviderId("PROVIDER OWNED"),
+ ownership = Ownership.MullvadOwned,
+ daita = false,
+ quic = Quic(inAddresses = listOf()),
+ lwo = true,
+ )
+private val DUMMY_RELAY_5 =
+ RelayItem.Location.Relay(
+ id =
+ GeoLocationId.Hostname(
+ city = GeoLocationId.City(GeoLocationId.Country("RCo4"), "Relay City 5"),
+ "Relay host 5",
+ ),
+ active = true,
+ provider = ProviderId("PROVIDER RENTED"),
+ ownership = Ownership.Rented,
+ daita = false,
+ quic = Quic(inAddresses = listOf()),
+ lwo = true,
+ )
+private val DUMMY_RELAY_6 =
+ RelayItem.Location.Relay(
+ id =
+ GeoLocationId.Hostname(
+ city = GeoLocationId.City(GeoLocationId.Country("RCo4"), "Relay City 5"),
+ "Relay host 6",
+ ),
+ active = true,
+ provider = ProviderId("PROVIDER RENTED"),
+ ownership = Ownership.Rented,
+ daita = true,
+ quic = Quic(inAddresses = listOf()),
+ lwo = true,
+ )
+private val DUMMY_RELAY_7 =
+ RelayItem.Location.Relay(
+ id =
+ GeoLocationId.Hostname(
+ city = GeoLocationId.City(GeoLocationId.Country("RCo4"), "Relay City 5"),
+ "Relay host 7",
+ ),
+ active = true,
+ provider = ProviderId("PROVIDER RENTED"),
+ ownership = Ownership.Rented,
+ daita = false,
+ quic = Quic(inAddresses = listOf()),
+ lwo = false,
+ )
+private val DUMMY_RELAY_8 =
+ RelayItem.Location.Relay(
+ id =
+ GeoLocationId.Hostname(
+ city = GeoLocationId.City(GeoLocationId.Country("RCo4"), "Relay City 5"),
+ "Relay host 8",
+ ),
+ active = true,
+ provider = ProviderId("PROVIDER RENTED"),
+ ownership = Ownership.Rented,
+ daita = false,
+ quic = null,
+ lwo = false,
+ )
+private val DUMMY_RELAY_9 =
+ RelayItem.Location.Relay(
+ id =
+ GeoLocationId.Hostname(
+ city = GeoLocationId.City(GeoLocationId.Country("RCo4"), "Relay City 5"),
+ "Relay host 9",
+ ),
+ active = true,
+ provider = ProviderId("PROVIDER RENTED"),
+ ownership = Ownership.Rented,
+ daita = true,
+ quic = null,
+ lwo = true,
+ )
+private val DUMMY_RELAY_10 =
+ RelayItem.Location.Relay(
+ id =
+ GeoLocationId.Hostname(
+ city = GeoLocationId.City(GeoLocationId.Country("RCo4"), "Relay City 5"),
+ "Relay host 10",
+ ),
+ active = true,
+ provider = ProviderId("PROVIDER OWNED"),
+ ownership = Ownership.MullvadOwned,
+ daita = true,
+ quic = null,
+ lwo = false,
+ )
+private val DUMMY_RELAY_11 =
+ RelayItem.Location.Relay(
+ id =
+ GeoLocationId.Hostname(
+ city = GeoLocationId.City(GeoLocationId.Country("RCo4"), "Relay City 5"),
+ "Relay host 11",
+ ),
+ active = true,
+ provider = ProviderId("PROVIDER OWNED"),
+ ownership = Ownership.MullvadOwned,
+ daita = false,
+ quic = Quic(inAddresses = listOf()),
+ lwo = false,
+ )
+private val DUMMY_RELAY_12 =
+ RelayItem.Location.Relay(
+ id =
+ GeoLocationId.Hostname(
+ city = GeoLocationId.City(GeoLocationId.Country("RCo4"), "Relay City 5"),
+ "Relay host 12",
+ ),
+ active = true,
+ provider = ProviderId("PROVIDER OWNED"),
+ ownership = Ownership.MullvadOwned,
+ daita = false,
+ quic = Quic(inAddresses = listOf()),
+ lwo = true,
+ )
+private val DUMMY_RELAY_CITY_1 =
+ RelayItem.Location.City(
+ name = "Relay City 1",
+ id = GeoLocationId.City(country = GeoLocationId.Country("RCo1"), code = "RCi1"),
+ relays = listOf(DUMMY_RELAY_1),
+ )
+private val DUMMY_RELAY_CITY_2 =
+ RelayItem.Location.City(
+ name = "Relay City 2",
+ id = GeoLocationId.City(country = GeoLocationId.Country("RCo2"), code = "RCi2"),
+ relays = listOf(DUMMY_RELAY_2),
+ )
+private val DUMMY_RELAY_CITY_3 =
+ RelayItem.Location.City(
+ name = "Relay City 3",
+ id = GeoLocationId.City(country = GeoLocationId.Country("RCo3"), code = "RCi3"),
+ relays = listOf(DUMMY_RELAY_3),
+ )
+private val DUMMY_RELAY_CITY_4 =
+ RelayItem.Location.City(
+ name = "Relay City 4",
+ id = GeoLocationId.City(country = GeoLocationId.Country("RCo4"), code = "RCi4"),
+ relays = listOf(DUMMY_RELAY_4),
+ )
+private val DUMMY_RELAY_CITY_5 =
+ RelayItem.Location.City(
+ name = "Relay City 5",
+ id = GeoLocationId.City(country = GeoLocationId.Country("RCo4"), code = "RCi5"),
+ relays =
+ listOf(
+ DUMMY_RELAY_5,
+ DUMMY_RELAY_6,
+ DUMMY_RELAY_7,
+ DUMMY_RELAY_8,
+ DUMMY_RELAY_9,
+ DUMMY_RELAY_10,
+ DUMMY_RELAY_11,
+ DUMMY_RELAY_12,
+ ),
+ )
+private val DUMMY_RELAY_COUNTRY_1 =
+ RelayItem.Location.Country(
+ name = "Relay Country 1",
+ id = GeoLocationId.Country("RCo1"),
+ cities = listOf(DUMMY_RELAY_CITY_1),
+ )
+private val DUMMY_RELAY_COUNTRY_2 =
+ RelayItem.Location.Country(
+ name = "Relay Country 2",
+ id = GeoLocationId.Country("RCo2"),
+ cities = listOf(DUMMY_RELAY_CITY_2),
+ )
+private val DUMMY_RELAY_COUNTRY_3 =
+ RelayItem.Location.Country(
+ name = "Relay Country 3",
+ id = GeoLocationId.Country("RCo3"),
+ cities = listOf(DUMMY_RELAY_CITY_3),
+ )
+private val DUMMY_RELAY_COUNTRY_4 =
+ RelayItem.Location.Country(
+ name = "Relay Country 4",
+ id = GeoLocationId.Country("RCo4"),
+ cities = listOf(DUMMY_RELAY_CITY_4, DUMMY_RELAY_CITY_5),
+ )
+
+val DUMMY_RELAY_COUNTRIES =
+ listOf(
+ DUMMY_RELAY_COUNTRY_1,
+ DUMMY_RELAY_COUNTRY_2,
+ DUMMY_RELAY_COUNTRY_3,
+ DUMMY_RELAY_COUNTRY_4,
+ )
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/util/Keyboard.kt b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/util/Keyboard.kt
index 024fd49407..7dad92d3bd 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/util/Keyboard.kt
+++ b/android/lib/feature/customlist/impl/src/androidTest/java/net/mullvad/mullvadvpn/customlist/impl/util/Keyboard.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.util
+package net.mullvad.mullvadvpn.customlist.impl.util
import androidx.compose.runtime.Composable
import androidx.compose.ui.ExperimentalComposeUiApi
diff --git a/android/lib/feature/customlist/impl/src/main/AndroidManifest.xml b/android/lib/feature/customlist/impl/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..8bdb7e14b3
--- /dev/null
+++ b/android/lib/feature/customlist/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/textfield/CustomListNameTextField.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/component/CustomListNameTextField.kt
index 639ab36172..dc439b63a9 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/CustomListNameTextField.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/component/CustomListNameTextField.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.textfield
+package net.mullvad.mullvadvpn.customlist.impl.component
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialog.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/create/CreateCustomListDialog.kt
index 4dc1d82e9e..2463630459 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialog.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/create/CreateCustomListDialog.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.dialog
+package net.mullvad.mullvadvpn.customlist.impl.screen.create
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -12,23 +12,20 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.compose.dropUnlessResumed
import com.ramcosta.composedestinations.annotation.Destination
-import com.ramcosta.composedestinations.generated.destinations.CustomListLocationsDestination
+import com.ramcosta.composedestinations.annotation.ExternalModuleGraph
+import com.ramcosta.composedestinations.generated.customlist.destinations.CustomListLocationsDestination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.result.ResultBackNavigator
import com.ramcosta.composedestinations.spec.DestinationStyle
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.MainGraph
-import net.mullvad.mullvadvpn.compose.state.CreateCustomListUiState
-import net.mullvad.mullvadvpn.compose.textfield.CustomListNameTextField
+import net.mullvad.mullvadvpn.customlist.impl.component.CustomListNameTextField
import net.mullvad.mullvadvpn.lib.model.CustomListAlreadyExists
import net.mullvad.mullvadvpn.lib.model.GeoLocationId
import net.mullvad.mullvadvpn.lib.model.communication.CustomListActionResultData
import net.mullvad.mullvadvpn.lib.ui.component.dialog.InputDialog
+import net.mullvad.mullvadvpn.lib.ui.resource.R
import net.mullvad.mullvadvpn.lib.ui.tag.CREATE_CUSTOM_LIST_DIALOG_INPUT_TEST_TAG
import net.mullvad.mullvadvpn.lib.ui.theme.AppTheme
import net.mullvad.mullvadvpn.lib.usecase.customlists.CreateWithLocationsError
-import net.mullvad.mullvadvpn.viewmodel.CreateCustomListDialogSideEffect
-import net.mullvad.mullvadvpn.viewmodel.CreateCustomListDialogViewModel
import org.koin.androidx.compose.koinViewModel
@Preview
@@ -63,7 +60,7 @@ private fun PreviewCreateCustomListDialogError() {
data class CreateCustomListNavArgs(val locationCode: GeoLocationId?)
@Composable
-@Destination<MainGraph>(
+@Destination<ExternalModuleGraph>(
style = DestinationStyle.Dialog::class,
navArgs = CreateCustomListNavArgs::class,
)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/CreateCustomListDialogViewModel.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/create/CreateCustomListDialogViewModel.kt
index 01f1d67d0b..76a247a9a2 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/CreateCustomListDialogViewModel.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/create/CreateCustomListDialogViewModel.kt
@@ -1,9 +1,9 @@
-package net.mullvad.mullvadvpn.viewmodel
+package net.mullvad.mullvadvpn.customlist.impl.screen.create
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.ramcosta.composedestinations.generated.destinations.CreateCustomListDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.CreateCustomListDestination
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
@@ -13,7 +13,6 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
-import net.mullvad.mullvadvpn.compose.state.CreateCustomListUiState
import net.mullvad.mullvadvpn.lib.common.constant.VIEW_MODEL_STOP_TIMEOUT
import net.mullvad.mullvadvpn.lib.model.CustomListId
import net.mullvad.mullvadvpn.lib.model.CustomListName
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/CreateCustomListUiState.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/create/CreateCustomListUiState.kt
index 1c8c1fe5d6..eb1acf8bde 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/CreateCustomListUiState.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/create/CreateCustomListUiState.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.state
+package net.mullvad.mullvadvpn.customlist.impl.screen.create
import net.mullvad.mullvadvpn.lib.usecase.customlists.CreateWithLocationsError
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialog.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/delete/DeleteCustomListConfirmationDialog.kt
index dca68f792c..c92d521c8c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialog.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/delete/DeleteCustomListConfirmationDialog.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.dialog
+package net.mullvad.mullvadvpn.customlist.impl.screen.delete
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@@ -7,19 +7,16 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.compose.dropUnlessResumed
import com.ramcosta.composedestinations.annotation.Destination
+import com.ramcosta.composedestinations.annotation.ExternalModuleGraph
import com.ramcosta.composedestinations.result.ResultBackNavigator
import com.ramcosta.composedestinations.spec.DestinationStyle
-import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.common.compose.CollectSideEffectWithLifecycle
-import net.mullvad.mullvadvpn.compose.screen.MainGraph
-import net.mullvad.mullvadvpn.compose.state.DeleteCustomListUiState
import net.mullvad.mullvadvpn.lib.model.CustomListId
import net.mullvad.mullvadvpn.lib.model.CustomListName
import net.mullvad.mullvadvpn.lib.model.communication.CustomListActionResultData
import net.mullvad.mullvadvpn.lib.ui.component.dialog.NegativeConfirmationDialog
+import net.mullvad.mullvadvpn.lib.ui.resource.R
import net.mullvad.mullvadvpn.lib.ui.theme.AppTheme
-import net.mullvad.mullvadvpn.viewmodel.DeleteCustomListConfirmationSideEffect
-import net.mullvad.mullvadvpn.viewmodel.DeleteCustomListConfirmationViewModel
import org.koin.androidx.compose.koinViewModel
@Preview
@@ -37,7 +34,7 @@ private fun PreviewRemoveDeviceConfirmationDialog() {
data class DeleteCustomListNavArgs(val customListId: CustomListId, val name: CustomListName)
@Composable
-@Destination<MainGraph>(
+@Destination<ExternalModuleGraph>(
style = DestinationStyle.Dialog::class,
navArgs = DeleteCustomListNavArgs::class,
)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeleteCustomListConfirmationViewModel.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/delete/DeleteCustomListConfirmationViewModel.kt
index 96934a5ac9..877cc271db 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeleteCustomListConfirmationViewModel.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/delete/DeleteCustomListConfirmationViewModel.kt
@@ -1,9 +1,9 @@
-package net.mullvad.mullvadvpn.viewmodel
+package net.mullvad.mullvadvpn.customlist.impl.screen.delete
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.ramcosta.composedestinations.generated.destinations.DeleteCustomListDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.DeleteCustomListDestination
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -12,7 +12,6 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
-import net.mullvad.mullvadvpn.compose.state.DeleteCustomListUiState
import net.mullvad.mullvadvpn.lib.common.constant.VIEW_MODEL_STOP_TIMEOUT
import net.mullvad.mullvadvpn.lib.model.CustomListId
import net.mullvad.mullvadvpn.lib.model.CustomListName
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/DeleteCustomListUiState.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/delete/DeleteCustomListUiState.kt
index 55f0933b6e..ec2aea1518 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/DeleteCustomListUiState.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/delete/DeleteCustomListUiState.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.state
+package net.mullvad.mullvadvpn.customlist.impl.screen.delete
import net.mullvad.mullvadvpn.lib.model.CustomListName
import net.mullvad.mullvadvpn.lib.usecase.customlists.DeleteWithUndoError
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DiscardChangesDialog.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/discard/DiscardChangesDialog.kt
index 09288526e0..6bdf308ece 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DiscardChangesDialog.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/discard/DiscardChangesDialog.kt
@@ -1,17 +1,17 @@
-package net.mullvad.mullvadvpn.compose.dialog
+package net.mullvad.mullvadvpn.customlist.impl.screen.discard
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.ramcosta.composedestinations.annotation.Destination
+import com.ramcosta.composedestinations.annotation.ExternalModuleGraph
import com.ramcosta.composedestinations.result.EmptyResultBackNavigator
import com.ramcosta.composedestinations.result.ResultBackNavigator
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.Confirmed
import net.mullvad.mullvadvpn.lib.ui.component.dialog.InfoConfirmationDialog
import net.mullvad.mullvadvpn.lib.ui.component.dialog.InfoConfirmationDialogTitleType
+import net.mullvad.mullvadvpn.lib.ui.resource.R
import net.mullvad.mullvadvpn.lib.ui.theme.AppTheme
@Preview
@@ -20,7 +20,7 @@ private fun PreviewDiscardChangesDialog() {
AppTheme { DiscardChanges(EmptyResultBackNavigator()) }
}
-@Destination<MainGraph>(style = DestinationStyle.Dialog::class)
+@Destination<ExternalModuleGraph>(style = DestinationStyle.Dialog::class)
@Composable
fun DiscardChanges(resultBackNavigator: ResultBackNavigator<Confirmed>) {
InfoConfirmationDialog(
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreen.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlist/EditCustomListScreen.kt
index 1cf3ea92e5..d1c89246cd 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreen.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlist/EditCustomListScreen.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.screen
+package net.mullvad.mullvadvpn.customlist.impl.screen.editlist
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
@@ -28,17 +28,15 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.compose.dropUnlessResumed
import com.ramcosta.composedestinations.annotation.Destination
-import com.ramcosta.composedestinations.generated.destinations.CustomListLocationsDestination
-import com.ramcosta.composedestinations.generated.destinations.DeleteCustomListDestination
-import com.ramcosta.composedestinations.generated.destinations.EditCustomListNameDestination
+import com.ramcosta.composedestinations.annotation.ExternalModuleGraph
+import com.ramcosta.composedestinations.generated.customlist.destinations.CustomListLocationsDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.DeleteCustomListDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.EditCustomListNameDestination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.result.NavResult
import com.ramcosta.composedestinations.result.ResultBackNavigator
import com.ramcosta.composedestinations.result.ResultRecipient
-import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.common.compose.dropUnlessResumed
-import net.mullvad.mullvadvpn.compose.preview.EditCustomListUiStatePreviewParameterProvider
-import net.mullvad.mullvadvpn.compose.state.EditCustomListUiState
import net.mullvad.mullvadvpn.core.animation.SlideInFromRightTransition
import net.mullvad.mullvadvpn.lib.model.CustomListId
import net.mullvad.mullvadvpn.lib.model.CustomListName
@@ -48,12 +46,12 @@ import net.mullvad.mullvadvpn.lib.ui.component.ScaffoldWithMediumTopBar
import net.mullvad.mullvadvpn.lib.ui.component.listitem.EditCustomListListItem
import net.mullvad.mullvadvpn.lib.ui.designsystem.MullvadCircularProgressIndicatorLarge
import net.mullvad.mullvadvpn.lib.ui.designsystem.Position
+import net.mullvad.mullvadvpn.lib.ui.resource.R
import net.mullvad.mullvadvpn.lib.ui.tag.DELETE_DROPDOWN_MENU_ITEM_TEST_TAG
import net.mullvad.mullvadvpn.lib.ui.tag.TOP_BAR_DROPDOWN_BUTTON_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.menuItemColors
-import net.mullvad.mullvadvpn.viewmodel.EditCustomListViewModel
import org.koin.androidx.compose.koinViewModel
@Preview("Content|Loading|NotFound")
@@ -76,7 +74,7 @@ private fun PreviewEditCustomListScreen(
data class EditCustomListNavArgs(val customListId: CustomListId)
@Composable
-@Destination<MainGraph>(
+@Destination<ExternalModuleGraph>(
style = SlideInFromRightTransition::class,
navArgs = EditCustomListNavArgs::class,
)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/EditCustomListUiState.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlist/EditCustomListUiState.kt
index 6af59be686..0c882c0a3f 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/EditCustomListUiState.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlist/EditCustomListUiState.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.state
+package net.mullvad.mullvadvpn.customlist.impl.screen.editlist
import net.mullvad.mullvadvpn.lib.model.CustomListId
import net.mullvad.mullvadvpn.lib.model.CustomListName
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/EditCustomListUiStatePreviewParameterProvider.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlist/EditCustomListUiStatePreviewParameterProvider.kt
index abd3e2743b..ad8f9220c9 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/EditCustomListUiStatePreviewParameterProvider.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlist/EditCustomListUiStatePreviewParameterProvider.kt
@@ -1,7 +1,6 @@
-package net.mullvad.mullvadvpn.compose.preview
+package net.mullvad.mullvadvpn.customlist.impl.screen.editlist
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import net.mullvad.mullvadvpn.compose.state.EditCustomListUiState
import net.mullvad.mullvadvpn.lib.model.CustomListId
import net.mullvad.mullvadvpn.lib.model.CustomListName
import net.mullvad.mullvadvpn.lib.model.GeoLocationId
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/EditCustomListViewModel.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlist/EditCustomListViewModel.kt
index 16f08e622b..fde5de1f12 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/EditCustomListViewModel.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlist/EditCustomListViewModel.kt
@@ -1,14 +1,13 @@
-package net.mullvad.mullvadvpn.viewmodel
+package net.mullvad.mullvadvpn.customlist.impl.screen.editlist
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.ramcosta.composedestinations.generated.destinations.EditCustomListDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.EditCustomListDestination
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.WhileSubscribed
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
-import net.mullvad.mullvadvpn.compose.state.EditCustomListUiState
import net.mullvad.mullvadvpn.lib.common.constant.VIEW_MODEL_STOP_TIMEOUT
import net.mullvad.mullvadvpn.lib.model.CustomListId
import net.mullvad.mullvadvpn.lib.repository.CustomListsRepository
diff --git a/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/ContentKey.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/ContentKey.kt
new file mode 100644
index 0000000000..125c74749c
--- /dev/null
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/ContentKey.kt
@@ -0,0 +1,6 @@
+package net.mullvad.mullvadvpn.customlist.impl.screen.editlocations
+
+object ContentKey {
+ const val PROGRESS = "progress"
+ const val EMPTY = "empty"
+}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/CustomListLocationUiStatePreviewParameterProvider.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/CustomListLocationUiStatePreviewParameterProvider.kt
index d07030047a..70ad19364a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/CustomListLocationUiStatePreviewParameterProvider.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/CustomListLocationUiStatePreviewParameterProvider.kt
@@ -1,8 +1,6 @@
-package net.mullvad.mullvadvpn.compose.preview
+package net.mullvad.mullvadvpn.customlist.impl.screen.editlocations
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import net.mullvad.mullvadvpn.compose.state.CustomListLocationsData
-import net.mullvad.mullvadvpn.compose.state.CustomListLocationsUiState
import net.mullvad.mullvadvpn.lib.common.Lce
import net.mullvad.mullvadvpn.lib.model.GeoLocationId
import net.mullvad.mullvadvpn.lib.ui.component.relaylist.CheckableRelayListItem
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreen.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/CustomListLocationsScreen.kt
index ffb9629961..9b2bc5fb90 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreen.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/CustomListLocationsScreen.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.screen
+package net.mullvad.mullvadvpn.customlist.impl.screen.editlocations
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Column
@@ -29,23 +29,16 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.compose.dropUnlessResumed
import com.ramcosta.composedestinations.annotation.Destination
-import com.ramcosta.composedestinations.generated.destinations.DiscardChangesDestination
+import com.ramcosta.composedestinations.annotation.ExternalModuleGraph
+import com.ramcosta.composedestinations.generated.customlist.destinations.DiscardChangesDestination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.result.ResultBackNavigator
import com.ramcosta.composedestinations.result.ResultRecipient
-import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.common.compose.CollectSideEffectWithLifecycle
import net.mullvad.mullvadvpn.common.compose.animateScrollAndCentralizeItem
-import net.mullvad.mullvadvpn.compose.component.EmptyRelayListText
-import net.mullvad.mullvadvpn.compose.constant.CommonContentKey
-import net.mullvad.mullvadvpn.compose.constant.ContentType
-import net.mullvad.mullvadvpn.compose.preview.CustomListLocationUiStatePreviewParameterProvider
-import net.mullvad.mullvadvpn.compose.screen.location.positionalPadding
-import net.mullvad.mullvadvpn.compose.state.CustomListLocationsData
-import net.mullvad.mullvadvpn.compose.state.CustomListLocationsUiState
-import net.mullvad.mullvadvpn.compose.textfield.SearchTextField
import net.mullvad.mullvadvpn.core.OnNavResultValue
import net.mullvad.mullvadvpn.core.animation.SlideInFromRightTransition
+import net.mullvad.mullvadvpn.customlist.impl.screen.lists.ContentType
import net.mullvad.mullvadvpn.lib.common.Lce
import net.mullvad.mullvadvpn.lib.model.CustomListId
import net.mullvad.mullvadvpn.lib.model.RelayItem
@@ -55,13 +48,13 @@ import net.mullvad.mullvadvpn.lib.ui.component.ScaffoldWithSmallTopBar
import net.mullvad.mullvadvpn.lib.ui.component.dialog.Confirmed
import net.mullvad.mullvadvpn.lib.ui.component.drawVerticalScrollbar
import net.mullvad.mullvadvpn.lib.ui.component.relaylist.CheckableRelayLocationCell
+import net.mullvad.mullvadvpn.lib.ui.component.relaylist.ItemPosition
import net.mullvad.mullvadvpn.lib.ui.designsystem.MullvadCircularProgressIndicatorLarge
+import net.mullvad.mullvadvpn.lib.ui.resource.R
import net.mullvad.mullvadvpn.lib.ui.tag.SAVE_BUTTON_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.CustomListLocationsSideEffect
-import net.mullvad.mullvadvpn.viewmodel.CustomListLocationsViewModel
import org.koin.androidx.compose.koinViewModel
@Preview("Content|Empty|Loading")
@@ -85,7 +78,7 @@ private fun PreviewCustomListLocationScreen(
data class CustomListLocationsNavArgs(val customListId: CustomListId, val newList: Boolean)
@Composable
-@Destination<MainGraph>(
+@Destination<ExternalModuleGraph>(
style = SlideInFromRightTransition::class,
navArgs = CustomListLocationsNavArgs::class,
)
@@ -223,15 +216,13 @@ private fun Actions(isSaveEnabled: Boolean, onSaveClick: () -> Unit) {
}
private fun LazyListScope.loading() {
- item(key = CommonContentKey.PROGRESS, contentType = ContentType.PROGRESS) {
+ item(key = ContentKey.PROGRESS, contentType = ContentType.PROGRESS) {
MullvadCircularProgressIndicatorLarge()
}
}
private fun LazyListScope.empty() {
- item(key = CommonContentKey.EMPTY, contentType = ContentType.EMPTY_TEXT) {
- EmptyRelayListText()
- }
+ item(key = ContentKey.EMPTY, contentType = ContentType.EMPTY_TEXT) { EmptyRelayListText() }
}
private fun LazyListScope.content(
@@ -240,7 +231,7 @@ private fun LazyListScope.content(
onRelaySelectedChanged: (RelayItem.Location, selected: Boolean) -> Unit,
) {
if (uiState.locations.isEmpty()) {
- item(key = CommonContentKey.EMPTY, contentType = ContentType.EMPTY_TEXT) {
+ item(key = ContentKey.EMPTY, contentType = ContentType.EMPTY_TEXT) {
LocationsEmptyText(searchTerm = uiState.searchTerm)
}
} else {
@@ -269,3 +260,13 @@ private fun LocationsEmptyText(searchTerm: String) {
modifier = Modifier.padding(Dimens.cellVerticalSpacing),
)
}
+
+// TODO Should maybe be in design system? Maybe if we use the correct composable we have it already?
+@Composable
+fun Modifier.positionalPadding(itemPosition: ItemPosition): Modifier =
+ when (itemPosition) {
+ ItemPosition.Top,
+ ItemPosition.Single -> padding(top = Dimens.miniPadding)
+ ItemPosition.Middle -> padding(top = Dimens.listItemDivider)
+ ItemPosition.Bottom -> padding(top = Dimens.listItemDivider, bottom = Dimens.miniPadding)
+ }
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/CustomListLocationsUiState.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/CustomListLocationsUiState.kt
index eaa1bbb928..67a722684a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/CustomListLocationsUiState.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/CustomListLocationsUiState.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.state
+package net.mullvad.mullvadvpn.customlist.impl.screen.editlocations
import net.mullvad.mullvadvpn.lib.common.Lce
import net.mullvad.mullvadvpn.lib.ui.component.relaylist.CheckableRelayListItem
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListLocationsViewModel.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/CustomListLocationsViewModel.kt
index 05785e7889..af3f4ec652 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListLocationsViewModel.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/CustomListLocationsViewModel.kt
@@ -1,11 +1,11 @@
-package net.mullvad.mullvadvpn.viewmodel
+package net.mullvad.mullvadvpn.customlist.impl.screen.editlocations
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import arrow.core.getOrElse
import arrow.core.raise.either
-import com.ramcosta.composedestinations.generated.destinations.CustomListLocationsDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.CustomListLocationsDestination
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -17,8 +17,6 @@ import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
-import net.mullvad.mullvadvpn.compose.state.CustomListLocationsData
-import net.mullvad.mullvadvpn.compose.state.CustomListLocationsUiState
import net.mullvad.mullvadvpn.lib.common.Lce
import net.mullvad.mullvadvpn.lib.common.constant.VIEW_MODEL_STOP_TIMEOUT
import net.mullvad.mullvadvpn.lib.common.util.relaylist.ancestors
diff --git a/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/EmptyRelayListText.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/EmptyRelayListText.kt
new file mode 100644
index 0000000000..6489568818
--- /dev/null
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/EmptyRelayListText.kt
@@ -0,0 +1,31 @@
+package net.mullvad.mullvadvpn.customlist.impl.screen.editlocations
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import net.mullvad.mullvadvpn.lib.ui.resource.R
+import net.mullvad.mullvadvpn.lib.ui.theme.Dimens
+
+@Composable
+fun EmptyRelayListText() {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier.padding(Dimens.cellVerticalSpacing),
+ ) {
+ Text(
+ text = stringResource(R.string.no_matching_servers_found_first_line),
+ style = MaterialTheme.typography.bodyMedium,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
+ Text(
+ text = stringResource(R.string.no_matching_servers_found_second_line),
+ style = MaterialTheme.typography.bodyMedium,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
+ }
+}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/SearchTextField.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/SearchTextField.kt
index a4b4b3a8ff..8e4591b6e5 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/SearchTextField.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editlocations/SearchTextField.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.textfield
+package net.mullvad.mullvadvpn.customlist.impl.screen.editlocations
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@@ -27,7 +27,7 @@ import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.tooling.preview.Preview
-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
import net.mullvad.mullvadvpn.lib.ui.theme.color.Alpha10
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialog.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editname/EditCustomListNameDialog.kt
index 60b2cc89e0..a2abfd1ff9 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialog.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editname/EditCustomListNameDialog.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.dialog
+package net.mullvad.mullvadvpn.customlist.impl.screen.editname
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@@ -9,13 +9,11 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.compose.dropUnlessResumed
import com.ramcosta.composedestinations.annotation.Destination
+import com.ramcosta.composedestinations.annotation.ExternalModuleGraph
import com.ramcosta.composedestinations.result.ResultBackNavigator
import com.ramcosta.composedestinations.spec.DestinationStyle
-import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.common.compose.CollectSideEffectWithLifecycle
-import net.mullvad.mullvadvpn.compose.screen.MainGraph
-import net.mullvad.mullvadvpn.compose.state.EditCustomListNameUiState
-import net.mullvad.mullvadvpn.compose.textfield.CustomListNameTextField
+import net.mullvad.mullvadvpn.customlist.impl.component.CustomListNameTextField
import net.mullvad.mullvadvpn.lib.model.CustomListId
import net.mullvad.mullvadvpn.lib.model.CustomListName
import net.mullvad.mullvadvpn.lib.model.GetCustomListError
@@ -23,11 +21,10 @@ import net.mullvad.mullvadvpn.lib.model.NameAlreadyExists
import net.mullvad.mullvadvpn.lib.model.UnknownCustomListError
import net.mullvad.mullvadvpn.lib.model.communication.CustomListActionResultData
import net.mullvad.mullvadvpn.lib.ui.component.dialog.InputDialog
+import net.mullvad.mullvadvpn.lib.ui.resource.R
import net.mullvad.mullvadvpn.lib.ui.tag.EDIT_CUSTOM_LIST_DIALOG_INPUT_TEST_TAG
import net.mullvad.mullvadvpn.lib.ui.theme.AppTheme
import net.mullvad.mullvadvpn.lib.usecase.customlists.RenameError
-import net.mullvad.mullvadvpn.viewmodel.EditCustomListNameDialogSideEffect
-import net.mullvad.mullvadvpn.viewmodel.EditCustomListNameDialogViewModel
import org.koin.androidx.compose.koinViewModel
@Preview
@@ -49,7 +46,7 @@ data class EditCustomListNameNavArgs(
)
@Composable
-@Destination<MainGraph>(
+@Destination<ExternalModuleGraph>(
style = DestinationStyle.Dialog::class,
navArgs = EditCustomListNameNavArgs::class,
)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/EditCustomListNameDialogViewModel.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editname/EditCustomListNameDialogViewModel.kt
index bc684851db..cd8e643fb6 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/EditCustomListNameDialogViewModel.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editname/EditCustomListNameDialogViewModel.kt
@@ -1,9 +1,9 @@
-package net.mullvad.mullvadvpn.viewmodel
+package net.mullvad.mullvadvpn.customlist.impl.screen.editname
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.ramcosta.composedestinations.generated.destinations.EditCustomListNameDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.EditCustomListNameDestination
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
@@ -13,7 +13,6 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
-import net.mullvad.mullvadvpn.compose.state.EditCustomListNameUiState
import net.mullvad.mullvadvpn.lib.common.constant.VIEW_MODEL_STOP_TIMEOUT
import net.mullvad.mullvadvpn.lib.model.CustomListName
import net.mullvad.mullvadvpn.lib.model.communication.CustomListAction
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/EditCustomListNameUiState.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editname/EditCustomListNameUiState.kt
index c7f89d8832..7ad3696410 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/EditCustomListNameUiState.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/editname/EditCustomListNameUiState.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.state
+package net.mullvad.mullvadvpn.customlist.impl.screen.editname
import net.mullvad.mullvadvpn.lib.usecase.customlists.RenameError
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreen.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/lists/CustomListsScreen.kt
index 72bf539871..c91e2d38d0 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreen.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/lists/CustomListsScreen.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.screen
+package net.mullvad.mullvadvpn.customlist.impl.screen.lists
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
@@ -26,19 +26,16 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.compose.dropUnlessResumed
import com.ramcosta.composedestinations.annotation.Destination
-import com.ramcosta.composedestinations.generated.destinations.CreateCustomListDestination
-import com.ramcosta.composedestinations.generated.destinations.EditCustomListDestination
+import com.ramcosta.composedestinations.annotation.ExternalModuleGraph
+import com.ramcosta.composedestinations.generated.customlist.destinations.CreateCustomListDestination
+import com.ramcosta.composedestinations.generated.customlist.destinations.EditCustomListDestination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.result.NavResult
import com.ramcosta.composedestinations.result.ResultRecipient
import kotlinx.coroutines.launch
-import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.common.compose.dropUnlessResumed
import net.mullvad.mullvadvpn.common.compose.itemsIndexedWithDivider
import net.mullvad.mullvadvpn.common.compose.showSnackbarImmediately
-import net.mullvad.mullvadvpn.compose.constant.ContentType
-import net.mullvad.mullvadvpn.compose.preview.CustomListsUiStatePreviewParameterProvider
-import net.mullvad.mullvadvpn.compose.state.CustomListsUiState
import net.mullvad.mullvadvpn.core.animation.SlideInFromRightTransition
import net.mullvad.mullvadvpn.lib.model.CustomList
import net.mullvad.mullvadvpn.lib.model.communication.CustomListActionResultData
@@ -47,10 +44,10 @@ import net.mullvad.mullvadvpn.lib.ui.component.ScaffoldWithMediumTopBar
import net.mullvad.mullvadvpn.lib.ui.component.listitem.NavigationListItem
import net.mullvad.mullvadvpn.lib.ui.component.positionForIndex
import net.mullvad.mullvadvpn.lib.ui.designsystem.MullvadCircularProgressIndicatorLarge
+import net.mullvad.mullvadvpn.lib.ui.resource.R
import net.mullvad.mullvadvpn.lib.ui.tag.NEW_LIST_BUTTON_TEST_TAG
import net.mullvad.mullvadvpn.lib.ui.theme.AppTheme
import net.mullvad.mullvadvpn.lib.ui.theme.Dimens
-import net.mullvad.mullvadvpn.viewmodel.CustomListsViewModel
import org.koin.androidx.compose.koinViewModel
@Preview("Content|Empty|Loading")
@@ -70,7 +67,7 @@ private fun PreviewAccountScreen(
}
@Composable
-@Destination<MainGraph>(style = SlideInFromRightTransition::class)
+@Destination<ExternalModuleGraph>(style = SlideInFromRightTransition::class)
fun CustomLists(
navigator: DestinationsNavigator,
editCustomListResultRecipient:
@@ -192,3 +189,9 @@ private fun LazyListScope.empty() {
)
}
}
+
+object ContentType {
+ const val ITEM = 2
+ const val PROGRESS = 6
+ const val EMPTY_TEXT = 7
+}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/CustomListsUiState.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/lists/CustomListsUiState.kt
index 63e3167881..d0f29af179 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/CustomListsUiState.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/lists/CustomListsUiState.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.compose.state
+package net.mullvad.mullvadvpn.customlist.impl.screen.lists
import net.mullvad.mullvadvpn.lib.model.CustomList
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/CustomListsUiStatePreviewParameterProvider.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/lists/CustomListsUiStatePreviewParameterProvider.kt
index ccaa3b1bf1..e35507381c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/CustomListsUiStatePreviewParameterProvider.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/lists/CustomListsUiStatePreviewParameterProvider.kt
@@ -1,7 +1,6 @@
-package net.mullvad.mullvadvpn.compose.preview
+package net.mullvad.mullvadvpn.customlist.impl.screen.lists
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import net.mullvad.mullvadvpn.compose.state.CustomListsUiState
import net.mullvad.mullvadvpn.lib.model.CustomList
import net.mullvad.mullvadvpn.lib.model.CustomListId
import net.mullvad.mullvadvpn.lib.model.CustomListName
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListsViewModel.kt b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/lists/CustomListsViewModel.kt
index 51973d3135..152eaa819f 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListsViewModel.kt
+++ b/android/lib/feature/customlist/impl/src/main/java/net/mullvad/mullvadvpn/customlist/impl/screen/lists/CustomListsViewModel.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.viewmodel
+package net.mullvad.mullvadvpn.customlist.impl.screen.lists
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@@ -8,7 +8,6 @@ import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
-import net.mullvad.mullvadvpn.compose.state.CustomListsUiState
import net.mullvad.mullvadvpn.lib.common.constant.VIEW_MODEL_STOP_TIMEOUT
import net.mullvad.mullvadvpn.lib.model.communication.CustomListAction
import net.mullvad.mullvadvpn.lib.repository.CustomListsRepository
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/CreateCustomListDialogViewModelTest.kt b/android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/CreateCustomListDialogViewModelTest.kt
index db7ba9d386..5d424c27ee 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/CreateCustomListDialogViewModelTest.kt
+++ b/android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/CreateCustomListDialogViewModelTest.kt
@@ -1,15 +1,17 @@
-package net.mullvad.mullvadvpn.viewmodel
+package net.mullvad.mullvadvpn.customlist.impl
import app.cash.turbine.test
import arrow.core.left
import arrow.core.right
-import com.ramcosta.composedestinations.generated.navargs.toSavedStateHandle
+import com.ramcosta.composedestinations.generated.customlist.navargs.toSavedStateHandle
import io.mockk.coEvery
import io.mockk.every
import io.mockk.mockk
import kotlin.test.assertIs
import kotlinx.coroutines.test.runTest
-import net.mullvad.mullvadvpn.compose.dialog.CreateCustomListNavArgs
+import net.mullvad.mullvadvpn.customlist.impl.screen.create.CreateCustomListDialogSideEffect
+import net.mullvad.mullvadvpn.customlist.impl.screen.create.CreateCustomListDialogViewModel
+import net.mullvad.mullvadvpn.customlist.impl.screen.create.CreateCustomListNavArgs
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.model.CustomListAlreadyExists
import net.mullvad.mullvadvpn.lib.model.CustomListId
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListLocationsViewModelTest.kt b/android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/CustomListLocationsViewModelTest.kt
index a00691c8f3..8aa5f4fece 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListLocationsViewModelTest.kt
+++ b/android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/CustomListLocationsViewModelTest.kt
@@ -1,17 +1,19 @@
-package net.mullvad.mullvadvpn.viewmodel
+package net.mullvad.mullvadvpn.customlist.impl
import app.cash.turbine.test
import arrow.core.right
-import com.ramcosta.composedestinations.generated.navargs.toSavedStateHandle
+import com.ramcosta.composedestinations.generated.customlist.navargs.toSavedStateHandle
import io.mockk.coEvery
import io.mockk.every
import io.mockk.mockk
import kotlin.test.assertIs
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
-import net.mullvad.mullvadvpn.compose.screen.CustomListLocationsNavArgs
-import net.mullvad.mullvadvpn.compose.state.CustomListLocationsData
-import net.mullvad.mullvadvpn.compose.state.CustomListLocationsUiState
+import net.mullvad.mullvadvpn.customlist.impl.screen.editlocations.CustomListLocationsData
+import net.mullvad.mullvadvpn.customlist.impl.screen.editlocations.CustomListLocationsNavArgs
+import net.mullvad.mullvadvpn.customlist.impl.screen.editlocations.CustomListLocationsSideEffect
+import net.mullvad.mullvadvpn.customlist.impl.screen.editlocations.CustomListLocationsUiState
+import net.mullvad.mullvadvpn.customlist.impl.screen.editlocations.CustomListLocationsViewModel
import net.mullvad.mullvadvpn.lib.common.Lce
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.common.test.assertLists
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListsViewModelTest.kt b/android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/CustomListsViewModelTest.kt
index e2cac33834..fe0bdc1c3f 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListsViewModelTest.kt
+++ b/android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/CustomListsViewModelTest.kt
@@ -1,4 +1,4 @@
-package net.mullvad.mullvadvpn.viewmodel
+package net.mullvad.mullvadvpn.customlist.impl
import app.cash.turbine.test
import io.mockk.coVerify
@@ -6,7 +6,8 @@ import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
-import net.mullvad.mullvadvpn.compose.state.CustomListsUiState
+import net.mullvad.mullvadvpn.customlist.impl.screen.lists.CustomListsUiState
+import net.mullvad.mullvadvpn.customlist.impl.screen.lists.CustomListsViewModel
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.model.CustomList
import net.mullvad.mullvadvpn.lib.model.communication.CustomListAction
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/DeleteCustomListConfirmationViewModelTest.kt b/android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/DeleteCustomListConfirmationViewModelTest.kt
index e7827f05c4..1e2f29323a 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/DeleteCustomListConfirmationViewModelTest.kt
+++ b/android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/DeleteCustomListConfirmationViewModelTest.kt
@@ -1,14 +1,16 @@
-package net.mullvad.mullvadvpn.viewmodel
+package net.mullvad.mullvadvpn.customlist.impl
import app.cash.turbine.test
import arrow.core.right
-import com.ramcosta.composedestinations.generated.navargs.toSavedStateHandle
+import com.ramcosta.composedestinations.generated.customlist.navargs.toSavedStateHandle
import io.mockk.coEvery
import io.mockk.every
import io.mockk.mockk
import kotlin.test.assertIs
import kotlinx.coroutines.test.runTest
-import net.mullvad.mullvadvpn.compose.dialog.DeleteCustomListNavArgs
+import net.mullvad.mullvadvpn.customlist.impl.screen.delete.DeleteCustomListConfirmationSideEffect
+import net.mullvad.mullvadvpn.customlist.impl.screen.delete.DeleteCustomListConfirmationViewModel
+import net.mullvad.mullvadvpn.customlist.impl.screen.delete.DeleteCustomListNavArgs
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.model.CustomListId
import net.mullvad.mullvadvpn.lib.model.CustomListName
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/EditCustomListNameDialogViewModelTest.kt b/android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/EditCustomListNameDialogViewModelTest.kt
index 6302bca9ab..c6edddf673 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/EditCustomListNameDialogViewModelTest.kt
+++ b/android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/EditCustomListNameDialogViewModelTest.kt
@@ -1,15 +1,17 @@
-package net.mullvad.mullvadvpn.viewmodel
+package net.mullvad.mullvadvpn.customlist.impl
import app.cash.turbine.test
import arrow.core.left
import arrow.core.right
-import com.ramcosta.composedestinations.generated.navargs.toSavedStateHandle
+import com.ramcosta.composedestinations.generated.customlist.navargs.toSavedStateHandle
import io.mockk.coEvery
import io.mockk.every
import io.mockk.mockk
import kotlin.test.assertIs
import kotlinx.coroutines.test.runTest
-import net.mullvad.mullvadvpn.compose.dialog.EditCustomListNameNavArgs
+import net.mullvad.mullvadvpn.customlist.impl.screen.editname.EditCustomListNameDialogSideEffect
+import net.mullvad.mullvadvpn.customlist.impl.screen.editname.EditCustomListNameDialogViewModel
+import net.mullvad.mullvadvpn.customlist.impl.screen.editname.EditCustomListNameNavArgs
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.model.CustomListId
import net.mullvad.mullvadvpn.lib.model.CustomListName
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/EditCustomListViewModelTest.kt b/android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/EditCustomListViewModelTest.kt
index 843bd0907c..dbfeeb7228 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/EditCustomListViewModelTest.kt
+++ b/android/lib/feature/customlist/impl/src/test/java/net/mullvad/mullvadvpn/customlist/impl/EditCustomListViewModelTest.kt
@@ -1,14 +1,15 @@
-package net.mullvad.mullvadvpn.viewmodel
+package net.mullvad.mullvadvpn.customlist.impl
import app.cash.turbine.test
-import com.ramcosta.composedestinations.generated.navargs.toSavedStateHandle
+import com.ramcosta.composedestinations.generated.customlist.navargs.toSavedStateHandle
import io.mockk.every
import io.mockk.mockk
import kotlin.test.assertIs
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
-import net.mullvad.mullvadvpn.compose.dialog.EditCustomListNameNavArgs
-import net.mullvad.mullvadvpn.compose.state.EditCustomListUiState
+import net.mullvad.mullvadvpn.customlist.impl.screen.editlist.EditCustomListUiState
+import net.mullvad.mullvadvpn.customlist.impl.screen.editlist.EditCustomListViewModel
+import net.mullvad.mullvadvpn.customlist.impl.screen.editname.EditCustomListNameNavArgs
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.model.CustomList
import net.mullvad.mullvadvpn.lib.model.CustomListId
diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts
index 6e30938cac..a7e78a441d 100644
--- a/android/settings.gradle.kts
+++ b/android/settings.gradle.kts
@@ -42,6 +42,7 @@ include(
":lib:feature:apiaccess:impl",
":lib:feature:appinfo:impl",
":lib:feature:appearance:impl",
+ ":lib:feature:customlist:impl",
":lib:feature:daita:impl",
":lib:feature:filter:impl",
":lib:feature:multihop:impl",