summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Göransson <david.goransson90@gmail.com>2023-12-14 16:42:30 +0100
committerAlbin <albin@mullvad.net>2023-12-14 16:54:21 +0100
commitfaf0c0af6419bec8ef610d20cd2c3dd5267394cc (patch)
treea44ee3bfd59efa48a0ef1ff64889651b8177c6c0
parent435d437f344d484270c1ce55d9f65985287bfac8 (diff)
downloadmullvadvpn-faf0c0af6419bec8ef610d20cd2c3dd5267394cc.tar.xz
mullvadvpn-faf0c0af6419bec8ef610d20cd2c3dd5267394cc.zip
Remove old fragment navigation
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CustomPortDialog.kt119
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeviceRemovalDialog.kt78
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoadingScreen.kt86
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/RedeemVoucherDialogScreen.kt32
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/TimingConstant.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginState.kt8
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/extension/ContextExtensions.kt23
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AccountFragment.kt56
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/BaseFragment.kt71
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt111
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceListFragment.kt91
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceRevokedFragment.kt42
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/FilterFragment.kt42
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/FragmentArgumentConstant.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoadingFragment.kt30
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoginFragment.kt89
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/OutOfTimeFragment.kt69
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/PrivacyDisclaimerFragment.kt56
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt57
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/RedeemVoucherDialogFragment.kt48
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SelectLocationFragment.kt52
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SettingsFragment.kt72
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragment.kt44
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ViewLogsFragment.kt36
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/VpnSettingsFragment.kt69
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/WelcomeFragment.kt68
-rw-r--r--android/app/src/main/res/layout/fragment_compose.xml9
-rw-r--r--android/app/src/main/res/layout/main.xml10
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ReportProblemModelTest.kt164
-rw-r--r--android/lib/resource/src/main/res/anim/do_nothing.xml6
-rw-r--r--android/lib/resource/src/main/res/anim/fragment_enter_from_bottom.xml6
-rw-r--r--android/lib/resource/src/main/res/anim/fragment_enter_from_right.xml6
-rw-r--r--android/lib/resource/src/main/res/anim/fragment_exit_to_bottom.xml6
-rw-r--r--android/lib/resource/src/main/res/anim/fragment_exit_to_left.xml6
-rw-r--r--android/lib/resource/src/main/res/anim/fragment_exit_to_right.xml6
-rw-r--r--android/lib/resource/src/main/res/anim/fragment_half_enter_from_left.xml6
-rw-r--r--android/lib/resource/src/main/res/anim/fragment_half_exit_to_left.xml6
37 files changed, 0 insertions, 1686 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CustomPortDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CustomPortDialog.kt
deleted file mode 100644
index a30e525e6d..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CustomPortDialog.kt
+++ /dev/null
@@ -1,119 +0,0 @@
-package net.mullvad.mullvadvpn.compose.dialog
-
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.testTag
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.tooling.preview.Preview
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.button.NegativeButton
-import net.mullvad.mullvadvpn.compose.button.PrimaryButton
-import net.mullvad.mullvadvpn.compose.test.CUSTOM_PORT_DIALOG_INPUT_TEST_TAG
-import net.mullvad.mullvadvpn.compose.textfield.CustomPortTextField
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.lib.theme.Dimens
-import net.mullvad.mullvadvpn.lib.theme.color.AlphaDescription
-import net.mullvad.mullvadvpn.model.PortRange
-import net.mullvad.mullvadvpn.util.asString
-import net.mullvad.mullvadvpn.util.isPortInValidRanges
-
-@Preview
-@Composable
-private fun PreviewCustomPortDialog() {
- AppTheme {
- CustomPortDialog(
- onSave = {},
- onReset = {},
- customPort = "",
- allowedPortRanges = listOf(PortRange(10, 10), PortRange(40, 50)),
- showReset = true,
- onDismissRequest = {}
- )
- }
-}
-
-@Composable
-fun CustomPortDialog(
- customPort: String,
- allowedPortRanges: List<PortRange>,
- showReset: Boolean,
- onSave: (customPortString: String) -> Unit,
- onReset: () -> Unit,
- onDismissRequest: () -> Unit
-) {
- val port = remember { mutableStateOf(customPort) }
-
- AlertDialog(
- title = {
- Text(
- text = stringResource(id = R.string.custom_port_dialog_title),
- style = MaterialTheme.typography.headlineSmall
- )
- },
- confirmButton = {
- Column(verticalArrangement = Arrangement.spacedBy(Dimens.buttonSpacing)) {
- PrimaryButton(
- text = stringResource(id = R.string.custom_port_dialog_submit),
- onClick = { onSave(port.value) },
- isEnabled =
- port.value.isNotEmpty() &&
- allowedPortRanges.isPortInValidRanges(port.value.toIntOrNull() ?: 0)
- )
- if (showReset) {
- NegativeButton(
- text = stringResource(R.string.custom_port_dialog_remove),
- onClick = onReset
- )
- }
- PrimaryButton(
- text = stringResource(id = R.string.cancel),
- onClick = onDismissRequest
- )
- }
- },
- text = {
- Column {
- CustomPortTextField(
- value = port.value,
- onSubmit = { input ->
- if (
- input.isNotEmpty() &&
- allowedPortRanges.isPortInValidRanges(input.toIntOrNull() ?: 0)
- ) {
- onSave(input)
- }
- },
- onValueChanged = { input -> port.value = input },
- isValidValue =
- port.value.isNotEmpty() &&
- allowedPortRanges.isPortInValidRanges(port.value.toIntOrNull() ?: 0),
- maxCharLength = 5,
- modifier = Modifier.testTag(CUSTOM_PORT_DIALOG_INPUT_TEST_TAG).fillMaxWidth()
- )
- Spacer(modifier = Modifier.height(Dimens.smallPadding))
- Text(
- text =
- stringResource(
- id = R.string.custom_port_dialog_valid_ranges,
- allowedPortRanges.asString()
- ),
- color = MaterialTheme.colorScheme.onBackground.copy(alpha = AlphaDescription),
- style = MaterialTheme.typography.bodySmall
- )
- }
- },
- containerColor = MaterialTheme.colorScheme.background,
- titleContentColor = MaterialTheme.colorScheme.onBackground,
- onDismissRequest = onDismissRequest
- )
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeviceRemovalDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeviceRemovalDialog.kt
deleted file mode 100644
index d99f9e62b7..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeviceRemovalDialog.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-package net.mullvad.mullvadvpn.compose.dialog
-
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.width
-import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusRequester
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.button.NegativeButton
-import net.mullvad.mullvadvpn.compose.button.PrimaryButton
-import net.mullvad.mullvadvpn.compose.component.HtmlText
-import net.mullvad.mullvadvpn.compose.component.textResource
-import net.mullvad.mullvadvpn.model.Device
-
-@Preview
-@Composable
-private fun PreviewShowDeviceRemovalDialog() {
- DeviceRemovalDialog(
- onDismiss = {},
- onConfirm = {},
- device = Device("test", "test", byteArrayOf(), "test")
- )
-}
-
-@Composable
-fun DeviceRemovalDialog(onDismiss: () -> Unit, onConfirm: () -> Unit, device: Device) {
- AlertDialog(
- onDismissRequest = onDismiss,
- title = {
- Column(
- horizontalAlignment = Alignment.CenterHorizontally,
- modifier = Modifier.padding(top = 0.dp).fillMaxWidth()
- ) {
- Image(
- painter = painterResource(id = R.drawable.icon_alert),
- contentDescription = "Remove",
- modifier = Modifier.width(50.dp).height(50.dp)
- )
- }
- },
- text = {
- val htmlFormattedDialogText =
- textResource(
- id = R.string.max_devices_confirm_removal_description,
- device.displayName()
- )
-
- HtmlText(htmlFormattedString = htmlFormattedDialogText, textSize = 16.sp.value)
- },
- dismissButton = {
- NegativeButton(
- onClick = onConfirm,
- text = stringResource(id = R.string.confirm_removal)
- )
- },
- confirmButton = {
- PrimaryButton(
- modifier = Modifier.focusRequester(FocusRequester()),
- onClick = onDismiss,
- text = stringResource(id = R.string.back)
- )
- },
- containerColor = MaterialTheme.colorScheme.background
- )
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoadingScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoadingScreen.kt
deleted file mode 100644
index 022ca06c53..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoadingScreen.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-package net.mullvad.mullvadvpn.compose.screen
-
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-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.graphics.compositeOver
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.text.style.TextAlign
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.component.ScaffoldWithTopBar
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.lib.theme.Dimens
-import net.mullvad.mullvadvpn.lib.theme.color.AlphaDescription
-
-@Preview
-@Composable
-private fun PreviewLoadingScreen() {
- AppTheme { LoadingScreen() }
-}
-
-@Composable
-fun LoadingScreen(onSettingsCogClicked: () -> Unit = {}) {
- val backgroundColor = MaterialTheme.colorScheme.primary
-
- ScaffoldWithTopBar(
- topBarColor = backgroundColor,
- statusBarColor = backgroundColor,
- navigationBarColor = backgroundColor,
- onSettingsClicked = onSettingsCogClicked,
- onAccountClicked = null,
- isIconAndLogoVisible = false,
- content = {
- Box(
- contentAlignment = Alignment.Center,
- modifier =
- Modifier.background(backgroundColor)
- .padding(it)
- .padding(bottom = it.calculateTopPadding())
- .fillMaxSize()
- ) {
- Column(
- verticalArrangement = Arrangement.Center,
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- Image(
- painter = painterResource(id = R.drawable.launch_logo),
- contentDescription = "",
- modifier = Modifier.size(120.dp)
- )
- Image(
- painter = painterResource(id = R.drawable.logo_text),
- contentDescription = "",
- alpha = 0.6f,
- modifier = Modifier.padding(top = 12.dp).height(18.dp)
- )
- Text(
- text = stringResource(id = R.string.connecting_to_daemon),
- fontSize = 13.sp,
- color =
- MaterialTheme.colorScheme.onPrimary
- .copy(alpha = AlphaDescription)
- .compositeOver(backgroundColor),
- modifier =
- Modifier.padding(top = 12.dp).padding(horizontal = Dimens.sideMargin),
- textAlign = TextAlign.Center
- )
- }
- }
- }
- )
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/RedeemVoucherDialogScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/RedeemVoucherDialogScreen.kt
deleted file mode 100644
index 1db18b01a3..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/RedeemVoucherDialogScreen.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package net.mullvad.mullvadvpn.compose.screen
-
-import android.content.res.Configuration
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.tooling.preview.Devices
-import androidx.compose.ui.tooling.preview.Preview
-import net.mullvad.mullvadvpn.compose.dialog.RedeemVoucherDialog
-import net.mullvad.mullvadvpn.compose.state.VoucherDialogUiState
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-
-@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, device = Devices.PIXEL_3)
-@Composable
-private fun PreviewRedeemVoucherDialogScreen() {
- AppTheme {
- RedeemVoucherDialogScreen(
- uiState = VoucherDialogUiState.INITIAL,
- onVoucherInputChange = {},
- onRedeem = {},
- onDismiss = {}
- )
- }
-}
-
-@Composable
-internal fun RedeemVoucherDialogScreen(
- uiState: VoucherDialogUiState,
- onVoucherInputChange: (String) -> Unit = {},
- onRedeem: (voucherCode: String) -> Unit,
- onDismiss: (isTimeAdded: Boolean) -> Unit
-) {
- RedeemVoucherDialog(uiState, onVoucherInputChange, onRedeem, onDismiss)
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/TimingConstant.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/TimingConstant.kt
deleted file mode 100644
index 2a09964a80..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/TimingConstant.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package net.mullvad.mullvadvpn.constant
-
-const val MINIMUM_LOADING_TIME_MILLIS = 500L
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginState.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginState.kt
deleted file mode 100644
index cece178267..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginState.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package net.mullvad.mullvadvpn.ui
-
-enum class LoginState {
- Initial,
- InProgress,
- Success,
- Failure,
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/extension/ContextExtensions.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/extension/ContextExtensions.kt
deleted file mode 100644
index e2e2f5c44c..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/extension/ContextExtensions.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package net.mullvad.mullvadvpn.ui.extension
-
-import android.content.ClipData
-import android.content.ClipboardManager
-import android.content.Context
-import androidx.fragment.app.Fragment
-import net.mullvad.mullvadvpn.ui.MainActivity
-
-fun Fragment.requireMainActivity(): MainActivity {
- return if (this.activity is MainActivity) {
- this.activity as MainActivity
- } else {
- throw IllegalStateException(
- "Fragment $this not attached to ${MainActivity::class.simpleName}."
- )
- }
-}
-
-fun Context.copyToClipboard(content: String, clipboardLabel: String) {
- val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
- val clipData = ClipData.newPlainText(clipboardLabel, content)
- clipboard.setPrimaryClip(clipData)
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AccountFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AccountFragment.kt
deleted file mode 100644
index 5225368dac..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AccountFragment.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.platform.ComposeView
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.AccountScreen
-import net.mullvad.mullvadvpn.constant.IS_PLAY_BUILD
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.viewmodel.AccountViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class AccountFragment : BaseFragment() {
- private val vm by viewModel<AccountViewModel>()
-
- @OptIn(ExperimentalMaterial3Api::class)
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- val state = vm.uiState.collectAsState().value
- AccountScreen(
- showSitePayment = IS_PLAY_BUILD.not(),
- uiState = state,
- uiSideEffect = vm.uiSideEffect,
- enterTransitionEndAction = vm.enterTransitionEndAction,
- onRedeemVoucherClick = { openRedeemVoucherFragment() },
- onManageAccountClick = vm::onManageAccountClick,
- onLogoutClick = vm::onLogoutClick,
- onPurchaseBillingProductClick = vm::startBillingPayment,
- onClosePurchaseResultDialog = vm::onClosePurchaseResultDialog,
- onBackClick = { activity?.onBackPressedDispatcher?.onBackPressed() }
- )
- }
- }
- }
- }
-
- override fun onEnterTransitionAnimationEnd() {
- vm.onTransitionAnimationEnd()
- }
-
- private fun openRedeemVoucherFragment() {
- val transaction = parentFragmentManager.beginTransaction()
- transaction.addToBackStack(null)
- RedeemVoucherDialogFragment().show(transaction, null)
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/BaseFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/BaseFragment.kt
deleted file mode 100644
index 99b9b42f09..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/BaseFragment.kt
+++ /dev/null
@@ -1,71 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.view.animation.Animation
-import android.view.animation.AnimationUtils
-import androidx.annotation.LayoutRes
-import androidx.core.view.ViewCompat
-import androidx.fragment.app.Fragment
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.emptyFlow
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.util.transitionFinished
-
-abstract class BaseFragment : Fragment {
- constructor() : super()
-
- constructor(@LayoutRes contentLayoutId: Int) : super(contentLayoutId)
-
- protected var transitionFinishedFlow: Flow<Unit> = emptyFlow()
- private set
-
- override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
- val zAdjustment =
- if (animationsToAdjustZorder.contains(nextAnim)) {
- 1f
- } else {
- 0f
- }
- ViewCompat.setTranslationZ(requireView(), zAdjustment)
- val anim =
- if (nextAnim != 0 && enter) {
- AnimationUtils.loadAnimation(context, nextAnim)?.apply {
- transitionFinishedFlow = transitionFinished()
- }
- } else {
- super.onCreateAnimation(transit, enter, nextAnim)
- }
- anim?.let {
- anim.setAnimationListener(
- object : Animation.AnimationListener {
- override fun onAnimationStart(animation: Animation?) {}
-
- override fun onAnimationRepeat(animation: Animation?) {}
-
- override fun onAnimationEnd(animation: Animation?) {
- if (enter) {
- onEnterTransitionAnimationEnd()
- }
- }
- },
- )
- }
- ?: run {
- if (enter) {
- onEnterTransitionAnimationEnd()
- }
- }
- return anim
- }
-
- open fun onEnterTransitionAnimationEnd() {}
-
- companion object {
- private val animationsToAdjustZorder =
- listOf(
- R.anim.fragment_enter_from_right,
- R.anim.fragment_exit_to_right,
- R.anim.fragment_enter_from_bottom,
- R.anim.fragment_exit_to_bottom
- )
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt
deleted file mode 100644
index 532787ff4f..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt
+++ /dev/null
@@ -1,111 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.content.Intent
-import android.net.Uri
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.platform.ComposeView
-import kotlinx.coroutines.flow.MutableStateFlow
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.ConnectScreen
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.ui.MainActivity
-import net.mullvad.mullvadvpn.util.appendHideNavOnPlayBuild
-import net.mullvad.mullvadvpn.viewmodel.ConnectViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class ConnectFragment : BaseFragment() {
-
- // Injected dependencies
- private val connectViewModel: ConnectViewModel by viewModel()
- private val _setNavigationBar = MutableStateFlow(false)
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- val view = inflater.inflate(R.layout.fragment_compose, container, false)
-
- view.findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- val state = connectViewModel.uiState.collectAsState().value
- val drawNavbar = _setNavigationBar.collectAsState()
- ConnectScreen(
- uiState = state,
- uiSideEffect = connectViewModel.uiSideEffect,
- drawNavigationBar = drawNavbar.value,
- onDisconnectClick = connectViewModel::onDisconnectClick,
- onReconnectClick = connectViewModel::onReconnectClick,
- onConnectClick = connectViewModel::onConnectClick,
- onCancelClick = connectViewModel::onCancelClick,
- onSwitchLocationClick = ::openSwitchLocationScreen,
- onToggleTunnelInfo = connectViewModel::toggleTunnelInfoExpansion,
- onUpdateVersionClick = { openDownloadUrl() },
- onManageAccountClick = connectViewModel::onManageAccountClick,
- onOpenOutOfTimeScreen = ::openOutOfTimeScreen,
- onSettingsClick = ::openSettingsView,
- onAccountClick = ::openAccountView,
- onDismissNewDeviceClick = connectViewModel::dismissNewDeviceNotification,
- )
- }
- }
-
- return view
- }
-
- private fun openDownloadUrl() {
- val intent =
- Intent(
- Intent.ACTION_VIEW,
- Uri.parse(
- requireContext().getString(R.string.download_url).appendHideNavOnPlayBuild()
- )
- )
- .apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK }
- requireContext().startActivity(intent)
- }
-
- private fun openSwitchLocationScreen() {
- parentFragmentManager.beginTransaction().apply {
- setCustomAnimations(
- R.anim.fragment_enter_from_bottom,
- R.anim.do_nothing,
- R.anim.do_nothing,
- R.anim.fragment_exit_to_bottom
- )
- replace(R.id.main_fragment, SelectLocationFragment())
- addToBackStack(null)
- commitAllowingStateLoss()
- }
- }
-
- private fun openOutOfTimeScreen() {
- parentFragmentManager.beginTransaction().apply {
- replace(R.id.main_fragment, OutOfTimeFragment())
- commitAllowingStateLoss()
- }
- }
-
- private fun openSettingsView() {
- (context as? MainActivity)?.openSettings()
- }
-
- private fun openAccountView() {
- (context as? MainActivity)?.openAccount()
- }
-
- override fun onPause() {
- super.onPause()
- _setNavigationBar.value = false
- }
-
- // TODO Temporary fix for handling in & out animations until we have Compose Navigation
- override fun onEnterTransitionAnimationEnd() {
- super.onEnterTransitionAnimationEnd()
- _setNavigationBar.value = true
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceListFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceListFragment.kt
deleted file mode 100644
index ab6de40dc2..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceListFragment.kt
+++ /dev/null
@@ -1,91 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.Toast
-import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.platform.ComposeView
-import androidx.fragment.app.Fragment
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.flowWithLifecycle
-import androidx.lifecycle.lifecycleScope
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.DeviceListScreen
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.ui.MainActivity
-import net.mullvad.mullvadvpn.viewmodel.DeviceListViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class DeviceListFragment : Fragment() {
-
- private val deviceListViewModel by viewModel<DeviceListViewModel>()
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- lifecycleScope.launchUiSubscriptionsOnResume()
- }
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- deviceListViewModel.accountToken = arguments?.getString(ACCOUNT_TOKEN_ARGUMENT_KEY)
-
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- val state = deviceListViewModel.uiState.collectAsState().value
- DeviceListScreen(
- state = state,
- onBackClick = { openLoginView(doTriggerAutoLogin = false) },
- onContinueWithLogin = { openLoginView(doTriggerAutoLogin = true) },
- onSettingsClicked = this@DeviceListFragment::openSettings,
- onDeviceRemovalClicked = deviceListViewModel::stageDeviceForRemoval,
- onDismissDeviceRemovalDialog = deviceListViewModel::clearStagedDevice,
- onConfirmDeviceRemovalDialog =
- deviceListViewModel::confirmRemovalOfStagedDevice
- )
- }
- }
- }
- }
-
- override fun onResume() {
- super.onResume()
- deviceListViewModel.clearStagedDevice()
- }
-
- private fun CoroutineScope.launchUiSubscriptionsOnResume() = launch {
- deviceListViewModel.toastMessages
- .flowWithLifecycle(lifecycle, Lifecycle.State.RESUMED)
- .collect { Toast.makeText(context, it, Toast.LENGTH_SHORT).show() }
- }
-
- private fun openLoginView(doTriggerAutoLogin: Boolean) {
- parentActivity()?.clearBackStack()
- val loginFragment =
- LoginFragment().apply {
- if (doTriggerAutoLogin && deviceListViewModel.accountToken != null) {
- arguments =
- Bundle().apply {
- putString(ACCOUNT_TOKEN_ARGUMENT_KEY, deviceListViewModel.accountToken)
- }
- }
- }
- parentFragmentManager.beginTransaction().apply {
- replace(R.id.main_fragment, loginFragment)
- commitAllowingStateLoss()
- }
- }
-
- private fun parentActivity(): MainActivity? {
- return (context as? MainActivity)
- }
-
- private fun openSettings() = parentActivity()?.openSettings()
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceRevokedFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceRevokedFragment.kt
deleted file mode 100644
index 4b744d568a..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceRevokedFragment.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.platform.ComposeView
-import androidx.fragment.app.Fragment
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.DeviceRevokedScreen
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.ui.MainActivity
-import net.mullvad.mullvadvpn.viewmodel.DeviceRevokedViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class DeviceRevokedFragment : Fragment() {
- private val deviceRevokedViewModel: DeviceRevokedViewModel by viewModel()
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- val state = deviceRevokedViewModel.uiState.collectAsState().value
- DeviceRevokedScreen(
- state = state,
- onSettingsClicked = this@DeviceRevokedFragment::openSettingsView,
- onGoToLoginClicked = deviceRevokedViewModel::onGoToLoginClicked
- )
- }
- }
- }
- }
-
- private fun openSettingsView() {
- (context as? MainActivity)?.openSettings()
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/FilterFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/FilterFragment.kt
deleted file mode 100644
index 17357d8cbf..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/FilterFragment.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.platform.ComposeView
-import androidx.fragment.app.Fragment
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.FilterScreen
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.viewmodel.FilterViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class FilterFragment : Fragment() {
-
- private val vm by viewModel<FilterViewModel>()
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- val state = vm.uiState.collectAsState().value
- FilterScreen(
- uiState = state,
- onSelectedOwnership = vm::setSelectedOwnership,
- onAllProviderCheckChange = vm::setAllProviders,
- onSelectedProviders = vm::setSelectedProvider,
- uiCloseAction = vm.uiSideEffect,
- onBackClick = { activity?.onBackPressedDispatcher?.onBackPressed() },
- onApplyClick = vm::onApplyButtonClicked
- )
- }
- }
- }
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/FragmentArgumentConstant.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/FragmentArgumentConstant.kt
deleted file mode 100644
index 7b066b1246..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/FragmentArgumentConstant.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-const val ACCOUNT_TOKEN_ARGUMENT_KEY = "accountToken"
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoadingFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoadingFragment.kt
deleted file mode 100644
index d2f0cbfb6e..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoadingFragment.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.ui.platform.ComposeView
-import androidx.fragment.app.Fragment
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.LoadingScreen
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.ui.MainActivity
-
-class LoadingFragment : Fragment() {
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme { LoadingScreen(this@LoadingFragment::openSettings) }
- }
- }
- }
-
- private fun openSettings() {
- (context as? MainActivity)?.openSettings()
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoginFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoginFragment.kt
deleted file mode 100644
index 92d58066ee..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoginFragment.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.collectAsState
-import androidx.compose.runtime.getValue
-import androidx.compose.ui.platform.ComposeView
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.LoginScreen
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.model.AccountToken
-import net.mullvad.mullvadvpn.ui.MainActivity
-import net.mullvad.mullvadvpn.viewmodel.LoginUiSideEffect
-import net.mullvad.mullvadvpn.viewmodel.LoginViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class LoginFragment : BaseFragment() {
- private val vm: LoginViewModel by viewModel()
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
-
- // TODO: Remove this when we have a better solution for login after clearing max devices
- val accountTokenArgument = arguments?.getString(ACCOUNT_TOKEN_ARGUMENT_KEY)
- if (accountTokenArgument != null) {
- // Login and set initial TextField value
- vm.onAccountNumberChange(accountTokenArgument)
- vm.login(accountTokenArgument)
- }
-
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- val uiState by vm.uiState.collectAsState()
- LaunchedEffect(Unit) {
- vm.uiSideEffect.collect {
- when (it) {
- LoginUiSideEffect.NavigateToWelcome,
- LoginUiSideEffect
- .NavigateToConnect -> {} // TODO Fix when we redo navigation
- is LoginUiSideEffect.TooManyDevices -> {
- navigateToDeviceListFragment(it.accountToken)
- }
- }
- }
- }
- LoginScreen(
- uiState,
- vm::login,
- vm::createAccount,
- vm::clearAccountHistory,
- vm::onAccountNumberChange,
- ::openSettingsView
- )
- }
- }
- }
- }
-
- private fun navigateToDeviceListFragment(accountToken: AccountToken) {
- val deviceFragment =
- DeviceListFragment().apply {
- arguments =
- Bundle().apply { putString(ACCOUNT_TOKEN_ARGUMENT_KEY, accountToken.value) }
- }
-
- parentFragmentManager.beginTransaction().apply {
- setCustomAnimations(
- R.anim.fragment_enter_from_right,
- R.anim.fragment_exit_to_left,
- R.anim.fragment_half_enter_from_left,
- R.anim.fragment_exit_to_right
- )
- replace(R.id.main_fragment, deviceFragment)
- addToBackStack(null)
- commitAllowingStateLoss()
- }
- }
-
- private fun openSettingsView() {
- (context as? MainActivity)?.openSettings()
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/OutOfTimeFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/OutOfTimeFragment.kt
deleted file mode 100644
index 5a1ae49e1a..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/OutOfTimeFragment.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.platform.ComposeView
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.OutOfTimeScreen
-import net.mullvad.mullvadvpn.constant.IS_PLAY_BUILD
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.ui.MainActivity
-import net.mullvad.mullvadvpn.viewmodel.OutOfTimeViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class OutOfTimeFragment : BaseFragment() {
-
- private val vm by viewModel<OutOfTimeViewModel>()
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- val state = vm.uiState.collectAsState().value
- OutOfTimeScreen(
- showSitePayment = IS_PLAY_BUILD.not(),
- uiState = state,
- uiSideEffect = vm.uiSideEffect,
- onSitePaymentClick = vm::onSitePaymentClick,
- onRedeemVoucherClick = ::openRedeemVoucherFragment,
- onSettingsClick = ::openSettingsView,
- onAccountClick = ::openAccountView,
- openConnectScreen = ::advanceToConnectScreen,
- onDisconnectClick = vm::onDisconnectClick,
- onPurchaseBillingProductClick = vm::startBillingPayment,
- onClosePurchaseResultDialog = vm::onClosePurchaseResultDialog
- )
- }
- }
- }
- }
-
- private fun openRedeemVoucherFragment() {
- val transaction = parentFragmentManager.beginTransaction()
- transaction.addToBackStack(null)
- RedeemVoucherDialogFragment { wasSuccessful -> if (wasSuccessful) advanceToConnectScreen() }
- .show(transaction, null)
- }
-
- private fun advanceToConnectScreen() {
- parentFragmentManager.beginTransaction().apply {
- replace(R.id.main_fragment, ConnectFragment())
- commitAllowingStateLoss()
- }
- }
-
- private fun openSettingsView() {
- (context as? MainActivity)?.openSettings()
- }
-
- private fun openAccountView() {
- (context as? MainActivity)?.openAccount()
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/PrivacyDisclaimerFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/PrivacyDisclaimerFragment.kt
deleted file mode 100644
index ed45382013..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/PrivacyDisclaimerFragment.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.content.Intent
-import android.net.Uri
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.ui.platform.ComposeView
-import androidx.fragment.app.Fragment
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.PrivacyDisclaimerScreen
-import net.mullvad.mullvadvpn.lib.endpoint.getApiEndpointConfigurationExtras
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.ui.MainActivity
-import net.mullvad.mullvadvpn.util.appendHideNavOnPlayBuild
-import net.mullvad.mullvadvpn.viewmodel.PrivacyDisclaimerViewModel
-import org.koin.android.ext.android.inject
-
-class PrivacyDisclaimerFragment : Fragment() {
-
- private val privacyDisclaimerViewModel: PrivacyDisclaimerViewModel by inject()
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- PrivacyDisclaimerScreen(
- onPrivacyPolicyLinkClicked = { openPrivacyPolicy() },
- onAcceptClicked = { handleAcceptedPrivacyDisclaimer() }
- )
- }
- }
- }
- }
-
- private fun handleAcceptedPrivacyDisclaimer() {
- privacyDisclaimerViewModel.setPrivacyDisclosureAccepted()
- (activity as? MainActivity)?.initializeStateHandlerAndServiceConnection(
- apiEndpointConfiguration = activity?.intent?.getApiEndpointConfigurationExtras()
- )
- }
-
- private fun openPrivacyPolicy() {
- val privacyPolicyUrlIntent =
- Intent(
- Intent.ACTION_VIEW,
- Uri.parse(getString(R.string.privacy_policy_url).appendHideNavOnPlayBuild())
- )
- context?.startActivity(privacyPolicyUrlIntent)
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt
deleted file mode 100644
index fd489e563f..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.platform.ComposeView
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.ReportProblemScreen
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.viewmodel.ReportProblemViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class ProblemReportFragment : BaseFragment() {
- private val vm by viewModel<ReportProblemViewModel>()
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
-
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- val uiState = vm.uiState.collectAsState().value
- ReportProblemScreen(
- uiState,
- onSendReport = { email, description -> vm.sendReport(email, description) },
- onDismissNoEmailDialog = vm::dismissConfirmNoEmail,
- onClearSendResult = vm::clearSendResult,
- onNavigateToViewLogs = { showLogs() },
- updateEmail = vm::updateEmail,
- updateDescription = vm::updateDescription
- ) {
- activity?.onBackPressed()
- }
- }
- }
- }
- }
-
- private fun showLogs() {
- parentFragmentManager.beginTransaction().apply {
- setCustomAnimations(
- R.anim.fragment_enter_from_right,
- R.anim.fragment_half_exit_to_left,
- R.anim.fragment_half_enter_from_left,
- R.anim.fragment_exit_to_right
- )
- replace(R.id.main_fragment, ViewLogsFragment())
- addToBackStack(null)
- commitAllowingStateLoss()
- }
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/RedeemVoucherDialogFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/RedeemVoucherDialogFragment.kt
deleted file mode 100644
index 2730fde547..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/RedeemVoucherDialogFragment.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.app.Dialog
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.platform.ComposeView
-import androidx.fragment.app.DialogFragment
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.RedeemVoucherDialogScreen
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.viewmodel.VoucherDialogViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class RedeemVoucherDialogFragment(val onDialogDismiss: (Boolean) -> Unit = {}) : DialogFragment() {
-
- private val vm by viewModel<VoucherDialogViewModel>()
- private lateinit var voucherDialog: Dialog
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- RedeemVoucherDialogScreen(
- uiState = vm.uiState.collectAsState().value,
- onVoucherInputChange = { vm.onVoucherInputChange(it) },
- onRedeem = { vm.onRedeem(it) },
- onDismiss = {
- onDismiss(voucherDialog)
- onDialogDismiss(it)
- }
- )
- }
- }
- }
- }
-
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- voucherDialog = super.onCreateDialog(savedInstanceState)
- return voucherDialog
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SelectLocationFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SelectLocationFragment.kt
deleted file mode 100644
index 64fdee71f6..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SelectLocationFragment.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.platform.ComposeView
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.SelectLocationScreen
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.ui.MainActivity
-import net.mullvad.mullvadvpn.viewmodel.SelectLocationViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class SelectLocationFragment : BaseFragment() {
-
- private val vm by viewModel<SelectLocationViewModel>()
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- val state = vm.uiState.collectAsState().value
- SelectLocationScreen(
- uiState = state,
- uiCloseAction = vm.uiCloseAction,
- enterTransitionEndAction = vm.enterTransitionEndAction,
- onSelectRelay = vm::selectRelay,
- onSearchTermInput = vm::onSearchTermInput,
- onBackClick = { activity?.onBackPressedDispatcher?.onBackPressed() },
- removeOwnershipFilter = vm::removeOwnerFilter,
- removeProviderFilter = vm::removeProviderFilter,
- onFilterClick = ::openFilterView
- )
- }
- }
- }
- }
-
- private fun openFilterView() {
- (context as? MainActivity)?.openFilter()
- }
-
- override fun onEnterTransitionAnimationEnd() {
- vm.onTransitionAnimationEnd()
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SettingsFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SettingsFragment.kt
deleted file mode 100644
index e5faf6bb11..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SettingsFragment.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.platform.ComposeView
-import androidx.fragment.app.Fragment
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.SettingsScreen
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.viewmodel.SettingsViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class SettingsFragment : BaseFragment() {
- private val vm by viewModel<SettingsViewModel>()
-
- @OptIn(ExperimentalMaterial3Api::class)
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- val state = vm.uiState.collectAsState().value
- SettingsScreen(
- uiState = state,
- enterTransitionEndAction = vm.enterTransitionEndAction,
- onVpnSettingCellClick = { openVpnSettingsFragment() },
- onSplitTunnelingCellClick = { openSplitTunnelingFragment() },
- onReportProblemCellClick = { openReportProblemFragment() },
- onBackClick = { activity?.onBackPressed() }
- )
- }
- }
- }
- }
-
- override fun onEnterTransitionAnimationEnd() {
- vm.onTransitionAnimationEnd()
- }
-
- private fun openFragment(fragment: Fragment) {
- parentFragmentManager.beginTransaction().apply {
- setCustomAnimations(
- R.anim.fragment_enter_from_right,
- R.anim.fragment_exit_to_left,
- R.anim.fragment_half_enter_from_left,
- R.anim.fragment_exit_to_right
- )
- replace(R.id.main_fragment, fragment)
- addToBackStack(null)
- commitAllowingStateLoss()
- }
- }
-
- private fun openVpnSettingsFragment() {
- openFragment(VpnSettingsFragment())
- }
-
- private fun openSplitTunnelingFragment() {
- openFragment(SplitTunnelingFragment())
- }
-
- private fun openReportProblemFragment() {
- openFragment(ProblemReportFragment())
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragment.kt
deleted file mode 100644
index 7004303ae8..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragment.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.platform.ComposeView
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.applist.ApplicationsIconManager
-import net.mullvad.mullvadvpn.compose.screen.SplitTunnelingScreen
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.viewmodel.SplitTunnelingViewModel
-import org.koin.android.ext.android.inject
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class SplitTunnelingFragment : BaseFragment() {
- private val viewModel: SplitTunnelingViewModel by viewModel()
- private val applicationsIconManager: ApplicationsIconManager by inject()
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- val state = viewModel.uiState.collectAsState().value
- SplitTunnelingScreen(
- uiState = state,
- onShowSystemAppsClick = viewModel::onShowSystemAppsClick,
- onExcludeAppClick = viewModel::onExcludeAppClick,
- onIncludeAppClick = viewModel::onIncludeAppClick,
- onBackClick = { activity?.onBackPressedDispatcher?.onBackPressed() },
- onResolveIcon = { packageName ->
- applicationsIconManager.getAppIcon(packageName)
- }
- )
- }
- }
- }
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ViewLogsFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ViewLogsFragment.kt
deleted file mode 100644
index 21931ab876..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ViewLogsFragment.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.platform.ComposeView
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.ViewLogsScreen
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.viewmodel.ViewLogsViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class ViewLogsFragment : BaseFragment() {
- private val vm by viewModel<ViewLogsViewModel>()
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
-
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- val uiState = vm.uiState.collectAsState()
- ViewLogsScreen(
- uiState = uiState.value,
- onBackClick = { activity?.onBackPressed() }
- )
- }
- }
- }
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/VpnSettingsFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/VpnSettingsFragment.kt
deleted file mode 100644
index 49d43e6b27..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/VpnSettingsFragment.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.platform.ComposeView
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.VpnSettingsScreen
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.viewmodel.VpnSettingsViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class VpnSettingsFragment : BaseFragment() {
- private val vm by viewModel<VpnSettingsViewModel>()
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- val state = vm.uiState.collectAsState().value
- VpnSettingsScreen(
- uiState = state,
- onMtuCellClick = vm::onMtuCellClick,
- onSaveMtuClick = vm::onSaveMtuClick,
- onRestoreMtuClick = vm::onRestoreMtuClick,
- onCancelMtuDialogClick = vm::onCancelDialogClick,
- onToggleAutoConnect = vm::onToggleAutoConnect,
- onToggleLocalNetworkSharing = vm::onToggleLocalNetworkSharing,
- onToggleDnsClick = vm::onToggleDnsClick,
- onToggleBlockAds = vm::onToggleBlockAds,
- onToggleBlockTrackers = vm::onToggleBlockTrackers,
- onToggleBlockMalware = vm::onToggleBlockMalware,
- onToggleBlockAdultContent = vm::onToggleBlockAdultContent,
- onToggleBlockGambling = vm::onToggleBlockGambling,
- onToggleBlockSocialMedia = vm::onToggleBlockSocialMedia,
- onDnsClick = vm::onDnsClick,
- onDnsInputChange = vm::onDnsInputChange,
- onSaveDnsClick = vm::onSaveDnsClick,
- onRemoveDnsClick = vm::onRemoveDnsClick,
- onCancelDnsDialogClick = vm::onCancelDns,
- onLocalNetworkSharingInfoClick = vm::onLocalNetworkSharingInfoClick,
- onContentsBlockersInfoClick = vm::onContentsBlockerInfoClick,
- onCustomDnsInfoClick = vm::onCustomDnsInfoClick,
- onMalwareInfoClick = vm::onMalwareInfoClick,
- onDismissInfoClick = vm::onDismissInfoClick,
- onBackClick = { activity?.onBackPressedDispatcher?.onBackPressed() },
- onStopEvent = vm::onStopEvent,
- toastMessagesSharedFlow = vm.toastMessages,
- onSelectObfuscationSetting = vm::onSelectObfuscationSetting,
- onObfuscationInfoClick = vm::onObfuscationInfoClick,
- onSelectQuantumResistanceSetting = vm::onSelectQuantumResistanceSetting,
- onQuantumResistanceInfoClicked = vm::onQuantumResistanceInfoClicked,
- onWireguardPortSelected = vm::onWireguardPortSelected,
- onWireguardPortInfoClicked = vm::onWireguardPortInfoClicked,
- onShowCustomPortDialog = vm::onShowCustomPortDialog,
- onCancelCustomPortDialogClick = vm::onCancelDialogClick,
- onCloseCustomPortDialog = vm::onCancelDialogClick
- )
- }
- }
- }
- }
-}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/WelcomeFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/WelcomeFragment.kt
deleted file mode 100644
index 5c5e0c83f8..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/WelcomeFragment.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-package net.mullvad.mullvadvpn.ui.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.runtime.collectAsState
-import androidx.compose.ui.platform.ComposeView
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.compose.screen.WelcomeScreen
-import net.mullvad.mullvadvpn.constant.IS_PLAY_BUILD
-import net.mullvad.mullvadvpn.lib.theme.AppTheme
-import net.mullvad.mullvadvpn.ui.MainActivity
-import net.mullvad.mullvadvpn.viewmodel.WelcomeViewModel
-import org.koin.androidx.viewmodel.ext.android.viewModel
-
-class WelcomeFragment : BaseFragment() {
-
- private val vm by viewModel<WelcomeViewModel>()
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- return inflater.inflate(R.layout.fragment_compose, container, false).apply {
- findViewById<ComposeView>(R.id.compose_view).setContent {
- AppTheme {
- val state = vm.uiState.collectAsState().value
- WelcomeScreen(
- showSitePayment = IS_PLAY_BUILD.not(),
- uiState = state,
- uiSideEffect = vm.uiSideEffect,
- onSitePaymentClick = vm::onSitePaymentClick,
- onRedeemVoucherClick = ::openRedeemVoucherFragment,
- onSettingsClick = ::openSettingsView,
- onAccountClick = ::openAccountView,
- openConnectScreen = ::advanceToConnectScreen,
- onPurchaseBillingProductClick = vm::startBillingPayment,
- onClosePurchaseResultDialog = vm::onClosePurchaseResultDialog
- )
- }
- }
- }
- }
-
- private fun openRedeemVoucherFragment() {
- val transaction = parentFragmentManager.beginTransaction()
- transaction.addToBackStack(null)
- RedeemVoucherDialogFragment { wasSuccessful -> if (wasSuccessful) advanceToConnectScreen() }
- .show(transaction, null)
- }
-
- private fun advanceToConnectScreen() {
- parentFragmentManager.beginTransaction().apply {
- replace(R.id.main_fragment, ConnectFragment())
- commitAllowingStateLoss()
- }
- }
-
- private fun openSettingsView() {
- (context as? MainActivity)?.openSettings()
- }
-
- private fun openAccountView() {
- (context as? MainActivity)?.openAccount()
- }
-}
diff --git a/android/app/src/main/res/layout/fragment_compose.xml b/android/app/src/main/res/layout/fragment_compose.xml
deleted file mode 100644
index a3a147d997..0000000000
--- a/android/app/src/main/res/layout/fragment_compose.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <androidx.compose.ui.platform.ComposeView android:id="@+id/compose_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-</FrameLayout>
diff --git a/android/app/src/main/res/layout/main.xml b/android/app/src/main/res/layout/main.xml
deleted file mode 100644
index 8e7356e766..0000000000
--- a/android/app/src/main/res/layout/main.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/main_fragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:filterTouchesWhenObscured="true">
- <!-- this component added to be able show compose dialog -->
- <androidx.compose.ui.platform.ComposeView android:id="@+id/compose_view"
- android:layout_width="match_parent"
- android:layout_height="@dimen/zero_size" />
-</FrameLayout>
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ReportProblemModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ReportProblemModelTest.kt
deleted file mode 100644
index e0b1c5274c..0000000000
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ReportProblemModelTest.kt
+++ /dev/null
@@ -1,164 +0,0 @@
-package net.mullvad.mullvadvpn.viewmodel
-
-import androidx.lifecycle.viewModelScope
-import app.cash.turbine.test
-import io.mockk.MockKAnnotations
-import io.mockk.coEvery
-import io.mockk.impl.annotations.MockK
-import io.mockk.verify
-import kotlin.test.assertEquals
-import kotlinx.coroutines.cancel
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.test.runTest
-import net.mullvad.mullvadvpn.dataproxy.MullvadProblemReport
-import net.mullvad.mullvadvpn.dataproxy.SendProblemReportResult
-import net.mullvad.mullvadvpn.dataproxy.UserReport
-import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
-import net.mullvad.mullvadvpn.repository.ProblemReportRepository
-import org.junit.After
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-
-class ReportProblemModelTest {
- @get:Rule val testCoroutineRule = TestCoroutineRule()
-
- @MockK private lateinit var mockMullvadProblemReport: MullvadProblemReport
- @MockK(relaxed = true) private lateinit var mockProblemReportRepository: ProblemReportRepository
-
- private val problemReportFlow = MutableStateFlow(UserReport("", ""))
-
- private lateinit var viewModel: ReportProblemViewModel
-
- @Before
- fun setUp() {
- MockKAnnotations.init(this)
- coEvery { mockMullvadProblemReport.collectLogs() } returns true
- coEvery { mockProblemReportRepository.problemReport } returns problemReportFlow
- viewModel = ReportProblemViewModel(mockMullvadProblemReport, mockProblemReportRepository)
- }
-
- @After
- fun tearDown() {
- viewModel.viewModelScope.coroutineContext.cancel()
- }
-
- @Test
- fun sendReportFailedToCollectLogs() = runTest {
- // Arrange
- coEvery { mockMullvadProblemReport.sendReport(any()) } returns
- SendProblemReportResult.Error.CollectLog
- val email = "my@email.com"
-
- // Act, Assert
- viewModel.uiState.test {
- assertEquals(null, awaitItem().sendingState)
- viewModel.sendReport(email, "My description")
- assertEquals(SendingReportUiState.Sending, awaitItem().sendingState)
- assertEquals(
- SendingReportUiState.Error(SendProblemReportResult.Error.CollectLog),
- awaitItem().sendingState
- )
- }
- }
-
- @Test
- fun sendReportFailedToSendReport() = runTest {
- // Arrange
- coEvery { mockMullvadProblemReport.sendReport(any()) } returns
- SendProblemReportResult.Error.SendReport
- val email = "my@email.com"
-
- // Act, Assert
- viewModel.uiState.test {
- assertEquals(null, awaitItem().sendingState)
- viewModel.sendReport(email, "My description")
- assertEquals(SendingReportUiState.Sending, awaitItem().sendingState)
- assertEquals(
- SendingReportUiState.Error(SendProblemReportResult.Error.SendReport),
- awaitItem().sendingState
- )
- }
- }
-
- @Test
- fun sendReportWithoutEmailSuccessfully() = runTest {
- // Arrange
- coEvery { mockMullvadProblemReport.sendReport(any()) } returns
- SendProblemReportResult.Success
- val email = ""
-
- // Act, Assert
- viewModel.uiState.test {
- assertEquals(ReportProblemUiState(false, null), awaitItem())
- viewModel.sendReport(email, "My description")
- assertEquals(ReportProblemUiState(true, null), awaitItem())
- viewModel.sendReport(email, "My description")
- assertEquals(ReportProblemUiState(false, SendingReportUiState.Sending), awaitItem())
- assertEquals(
- ReportProblemUiState(false, SendingReportUiState.Success(null)),
- awaitItem()
- )
- }
- }
-
- @Test
- fun sendReportSuccessfully() = runTest {
- // Arrange
- coEvery { mockMullvadProblemReport.collectLogs() } returns true
- coEvery { mockMullvadProblemReport.sendReport(any()) } returns
- SendProblemReportResult.Success
- val email = "my@email.com"
-
- // Act, Assert
- viewModel.uiState.test {
- assertEquals(awaitItem(), ReportProblemUiState(false, null))
- viewModel.sendReport(email, "My description")
-
- assertEquals(awaitItem(), ReportProblemUiState(false, SendingReportUiState.Sending))
- assertEquals(
- awaitItem(),
- ReportProblemUiState(false, SendingReportUiState.Success(email))
- )
- }
- }
-
- @Test
- fun testUpdateEmail() = runTest {
- // Arrange
- val email = "my@email.com"
-
- // Act
- viewModel.updateEmail(email)
-
- // Assert
- verify { mockProblemReportRepository.setEmail(email) }
- }
-
- @Test
- fun testUpdateDescription() = runTest {
- // Arrange
- val description = "My description"
-
- // Act
- viewModel.updateDescription(description)
-
- // Assert
- verify { mockProblemReportRepository.setDescription(description) }
- }
-
- @Test
- fun testUpdateProblemReport() = runTest {
- // Arrange
- val userReport = UserReport("my@email.com", "My description")
-
- // Act, Assert
- viewModel.uiState.test {
- awaitItem()
- problemReportFlow.value = userReport
- val result = awaitItem()
- assertEquals(userReport.email, result.email)
- assertEquals(userReport.description, result.description)
- }
- }
-}
diff --git a/android/lib/resource/src/main/res/anim/do_nothing.xml b/android/lib/resource/src/main/res/anim/do_nothing.xml
deleted file mode 100644
index 8cb6866d6d..0000000000
--- a/android/lib/resource/src/main/res/anim/do_nothing.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromYDelta="0"
- android:toYDelta="0"
- android:duration="@integer/transition_animation_duration" />
-</set>
diff --git a/android/lib/resource/src/main/res/anim/fragment_enter_from_bottom.xml b/android/lib/resource/src/main/res/anim/fragment_enter_from_bottom.xml
deleted file mode 100644
index 337392e881..0000000000
--- a/android/lib/resource/src/main/res/anim/fragment_enter_from_bottom.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromYDelta="100%p"
- android:toYDelta="0"
- android:duration="@integer/transition_animation_duration" />
-</set>
diff --git a/android/lib/resource/src/main/res/anim/fragment_enter_from_right.xml b/android/lib/resource/src/main/res/anim/fragment_enter_from_right.xml
deleted file mode 100644
index 5ba3b5c3f8..0000000000
--- a/android/lib/resource/src/main/res/anim/fragment_enter_from_right.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromXDelta="100%p"
- android:toXDelta="0"
- android:duration="@integer/transition_animation_duration" />
-</set>
diff --git a/android/lib/resource/src/main/res/anim/fragment_exit_to_bottom.xml b/android/lib/resource/src/main/res/anim/fragment_exit_to_bottom.xml
deleted file mode 100644
index dc1261114a..0000000000
--- a/android/lib/resource/src/main/res/anim/fragment_exit_to_bottom.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromYDelta="0"
- android:toYDelta="100%p"
- android:duration="@integer/transition_animation_duration" />
-</set>
diff --git a/android/lib/resource/src/main/res/anim/fragment_exit_to_left.xml b/android/lib/resource/src/main/res/anim/fragment_exit_to_left.xml
deleted file mode 100644
index 9ffa2c9877..0000000000
--- a/android/lib/resource/src/main/res/anim/fragment_exit_to_left.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromXDelta="0%p"
- android:toXDelta="-100%p"
- android:duration="@integer/transition_animation_duration" />
-</set>
diff --git a/android/lib/resource/src/main/res/anim/fragment_exit_to_right.xml b/android/lib/resource/src/main/res/anim/fragment_exit_to_right.xml
deleted file mode 100644
index d794200982..0000000000
--- a/android/lib/resource/src/main/res/anim/fragment_exit_to_right.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromXDelta="0"
- android:toXDelta="100%p"
- android:duration="@integer/transition_animation_duration" />
-</set>
diff --git a/android/lib/resource/src/main/res/anim/fragment_half_enter_from_left.xml b/android/lib/resource/src/main/res/anim/fragment_half_enter_from_left.xml
deleted file mode 100644
index 67e7b7364e..0000000000
--- a/android/lib/resource/src/main/res/anim/fragment_half_enter_from_left.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromXDelta="-50%p"
- android:toXDelta="0"
- android:duration="@integer/transition_animation_duration" />
-</set>
diff --git a/android/lib/resource/src/main/res/anim/fragment_half_exit_to_left.xml b/android/lib/resource/src/main/res/anim/fragment_half_exit_to_left.xml
deleted file mode 100644
index bfac81df2e..0000000000
--- a/android/lib/resource/src/main/res/anim/fragment_half_exit_to_left.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
- <translate android:fromXDelta="0%p"
- android:toXDelta="-50%p"
- android:duration="@integer/transition_animation_duration" />
-</set>