diff options
| author | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2023-08-24 16:56:49 +0200 |
|---|---|---|
| committer | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2023-09-06 09:06:40 +0200 |
| commit | 7e8158b02b5ba5af654c3d705d29dee1e65b74ef (patch) | |
| tree | dee30f6d67c088f8988ea796827b049b04366ce2 /android | |
| parent | 31e1b5d395e9622f8ce64d8b1a9f11716bfe1532 (diff) | |
| download | mullvadvpn-7e8158b02b5ba5af654c3d705d29dee1e65b74ef.tar.xz mullvadvpn-7e8158b02b5ba5af654c3d705d29dee1e65b74ef.zip | |
Move open account view code from connect fragment to view model
Diffstat (limited to 'android')
3 files changed, 48 insertions, 19 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt index ec8f3e885b..34c4104f7a 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt @@ -15,15 +15,20 @@ import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableLongStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.compose.button.ConnectionButton import net.mullvad.mullvadvpn.compose.button.SwitchLocationButton @@ -36,9 +41,11 @@ import net.mullvad.mullvadvpn.compose.test.CONNECT_BUTTON_TEST_TAG import net.mullvad.mullvadvpn.compose.test.LOCATION_INFO_TEST_TAG import net.mullvad.mullvadvpn.compose.test.RECONNECT_BUTTON_TEST_TAG import net.mullvad.mullvadvpn.compose.test.SELECT_LOCATION_BUTTON_TEST_TAG +import net.mullvad.mullvadvpn.lib.common.util.openAccountPageInBrowser import net.mullvad.mullvadvpn.lib.theme.AppTheme import net.mullvad.mullvadvpn.lib.theme.Dimens import net.mullvad.mullvadvpn.model.TunnelState +import net.mullvad.mullvadvpn.viewmodel.ConnectViewModel import net.mullvad.talpid.tunnel.ActionAfterDisconnect private const val CONNECT_BUTTON_THROTTLE_MILLIS = 1000 @@ -47,12 +54,18 @@ private const val CONNECT_BUTTON_THROTTLE_MILLIS = 1000 @Composable fun PreviewConnectScreen() { val state = ConnectUiState.INITIAL - AppTheme { ConnectScreen(state) } + AppTheme { + ConnectScreen( + uiState = state, + viewActions = MutableSharedFlow<ConnectViewModel.ViewAction>().asSharedFlow() + ) + } } @Composable fun ConnectScreen( uiState: ConnectUiState, + viewActions: SharedFlow<ConnectViewModel.ViewAction>, onDisconnectClick: () -> Unit = {}, onReconnectClick: () -> Unit = {}, onConnectClick: () -> Unit = {}, @@ -60,8 +73,17 @@ fun ConnectScreen( onSwitchLocationClick: () -> Unit = {}, onToggleTunnelInfo: () -> Unit = {}, onUpdateVersionClick: () -> Unit = {}, - onShowAccountClick: () -> Unit = {} + onManageAccountClick: () -> Unit = {} ) { + val context = LocalContext.current + LaunchedEffect(key1 = Unit) { + viewActions.collect { viewAction -> + if (viewAction is ConnectViewModel.ViewAction.OpenAccountManagementPageInBrowser) { + context.openAccountPageInBrowser(viewAction.token) + } + } + } + val scrollState = rememberScrollState() var lastConnectionActionTimestamp by remember { mutableLongStateOf(0L) } @@ -85,7 +107,7 @@ fun ConnectScreen( Notification( connectNotificationState = uiState.connectNotificationState, onClickUpdateVersion = onUpdateVersionClick, - onClickShowAccount = onShowAccountClick + onClickShowAccount = onManageAccountClick ) Spacer(modifier = Modifier.weight(1f)) if ( 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 index 8ea48d99ce..7bd3c56edd 100644 --- 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 @@ -22,19 +22,15 @@ import net.mullvad.mullvadvpn.lib.theme.AppTheme import net.mullvad.mullvadvpn.model.TunnelState import net.mullvad.mullvadvpn.ui.NavigationBarPainter import net.mullvad.mullvadvpn.ui.paintNavigationBar -import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager -import net.mullvad.mullvadvpn.ui.serviceconnection.authTokenCache import net.mullvad.mullvadvpn.ui.widget.HeaderBar import net.mullvad.mullvadvpn.viewmodel.ConnectViewModel import net.mullvad.talpid.tunnel.ErrorStateCause -import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.viewModel class ConnectFragment : BaseFragment(), NavigationBarPainter { // Injected dependencies private val connectViewModel: ConnectViewModel by viewModel() - private val serviceConnectionManager: ServiceConnectionManager by inject() private lateinit var headerBar: HeaderBar @@ -62,6 +58,7 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter { val state = connectViewModel.uiState.collectAsState().value ConnectScreen( uiState = state, + viewActions = connectViewModel.viewActions, onDisconnectClick = connectViewModel::onDisconnectClick, onReconnectClick = connectViewModel::onReconnectClick, onConnectClick = connectViewModel::onConnectClick, @@ -69,7 +66,7 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter { onSwitchLocationClick = { openSwitchLocationScreen() }, onToggleTunnelInfo = connectViewModel::toggleTunnelInfoExpansion, onUpdateVersionClick = { openDownloadUrl() }, - onShowAccountClick = { openAccountUrl() } + onManageAccountClick = connectViewModel::onManageAccountClick ) } } @@ -96,17 +93,6 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter { requireContext().startActivity(intent) } - private fun openAccountUrl() { - // TODO Move this to the viewmodel - lifecycleScope.launch { - serviceConnectionManager.authTokenCache()?.fetchAuthToken()?.let { token -> - val url = getString(R.string.account_url) - val ready = Uri.parse("$url?token=$token") - requireContext().startActivity(Intent(Intent.ACTION_VIEW, ready)) - } - } - } - private fun CoroutineScope.launchUiSubscriptionsOnResume() = launch { repeatOnLifecycle(Lifecycle.State.RESUMED) { launchViewModelSubscription() } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt index 5be9163051..b67cd754c4 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt @@ -5,10 +5,12 @@ import androidx.lifecycle.viewModelScope import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.emptyFlow @@ -17,6 +19,7 @@ import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.launch import net.mullvad.mullvadvpn.compose.state.ConnectNotificationState import net.mullvad.mullvadvpn.compose.state.ConnectUiState import net.mullvad.mullvadvpn.model.AccountExpiry @@ -29,6 +32,7 @@ import net.mullvad.mullvadvpn.ui.serviceconnection.RelayListListener import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionContainer import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionState +import net.mullvad.mullvadvpn.ui.serviceconnection.authTokenCache import net.mullvad.mullvadvpn.ui.serviceconnection.connectionProxy import net.mullvad.mullvadvpn.util.appVersionCallbackFlow import net.mullvad.mullvadvpn.util.callbackFlowFromNotifier @@ -44,6 +48,9 @@ class ConnectViewModel( private val isVersionInfoNotificationEnabled: Boolean, accountRepository: AccountRepository, ) : ViewModel() { + private val _viewActions = MutableSharedFlow<ViewAction>(extraBufferCapacity = 1) + val viewActions = _viewActions.asSharedFlow() + private val _shared: SharedFlow<ServiceConnectionContainer> = serviceConnectionManager.connectionState .flatMapLatest { state -> @@ -190,6 +197,20 @@ class ConnectViewModel( serviceConnectionManager.connectionProxy()?.disconnect() } + fun onManageAccountClick() { + viewModelScope.launch { + _viewActions.tryEmit( + ViewAction.OpenAccountManagementPageInBrowser( + serviceConnectionManager.authTokenCache()?.fetchAuthToken() ?: "" + ) + ) + } + } + + sealed interface ViewAction { + data class OpenAccountManagementPageInBrowser(val token: String) : ViewAction + } + companion object { const val UI_STATE_DEBOUNCE_DURATION_MILLIS: Long = 200 } |
