Skip to content

Commit

Permalink
Fix sideeffect types
Browse files Browse the repository at this point in the history
  • Loading branch information
Rawa committed Dec 13, 2023
1 parent 560a1fe commit 7e8d58f
Show file tree
Hide file tree
Showing 16 changed files with 99 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.navigation.popUpTo
import com.ramcosta.composedestinations.result.NavResult
import com.ramcosta.composedestinations.result.ResultRecipient
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.R
Expand Down Expand Up @@ -153,7 +153,7 @@ fun Account(
@Composable
fun AccountScreen(
uiState: AccountUiState,
uiSideEffect: SharedFlow<AccountViewModel.UiSideEffect>,
uiSideEffect: Flow<AccountViewModel.UiSideEffect>,
onCopyAccountNumber: (String) -> Unit = {},
onRedeemVoucherClick: () -> Unit = {},
onManageAccountClick: () -> Unit = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package net.mullvad.mullvadvpn.viewmodel
import android.app.Activity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
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.PaymentState
Expand All @@ -29,9 +30,8 @@ class AccountViewModel(
private val paymentUseCase: PaymentUseCase,
deviceRepository: DeviceRepository
) : ViewModel() {

private val _uiSideEffect = MutableSharedFlow<UiSideEffect>(extraBufferCapacity = 1)
val uiSideEffect = _uiSideEffect.asSharedFlow()
private val _uiSideEffect = Channel<UiSideEffect>(1, BufferOverflow.DROP_OLDEST)
val uiSideEffect = _uiSideEffect.receiveAsFlow()

val uiState: StateFlow<AccountUiState> =
combine(
Expand All @@ -57,7 +57,7 @@ class AccountViewModel(

fun onManageAccountClick() {
viewModelScope.launch {
_uiSideEffect.tryEmit(
_uiSideEffect.send(
UiSideEffect.OpenAccountManagementPageInBrowser(
serviceConnectionManager.authTokenCache()?.fetchAuthToken() ?: ""
)
Expand All @@ -67,11 +67,11 @@ class AccountViewModel(

fun onLogoutClick() {
accountRepository.logout()
viewModelScope.launch { _uiSideEffect.emit(UiSideEffect.NavigateToLogin) }
viewModelScope.launch { _uiSideEffect.send(UiSideEffect.NavigateToLogin) }
}

fun onCopyAccountNumber(accountNumber: String) {
viewModelScope.launch { _uiSideEffect.emit(UiSideEffect.CopyAccountNumber(accountNumber)) }
viewModelScope.launch { _uiSideEffect.send(UiSideEffect.CopyAccountNumber(accountNumber)) }
}

fun startBillingPayment(productId: ProductId, activityProvider: () -> Activity) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@ package net.mullvad.mullvadvpn.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
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
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -55,8 +56,8 @@ class ConnectViewModel(
private val outOfTimeUseCase: OutOfTimeUseCase,
private val paymentUseCase: PaymentUseCase
) : ViewModel() {
private val _uiSideEffect = MutableSharedFlow<UiSideEffect>(extraBufferCapacity = 1)
val uiSideEffect = _uiSideEffect.asSharedFlow()
private val _uiSideEffect = Channel<UiSideEffect>(1, BufferOverflow.DROP_OLDEST)
val uiSideEffect = _uiSideEffect.receiveAsFlow()

private val _shared: SharedFlow<ServiceConnectionContainer> =
serviceConnectionManager.connectionState
Expand Down Expand Up @@ -138,7 +139,7 @@ class ConnectViewModel(
viewModelScope.launch {
// This once we get isOutOfTime true we will navigate to OutOfTime view.
outOfTimeUseCase.isOutOfTime().first { it == true }
_uiSideEffect.emit(UiSideEffect.OutOfTime)
_uiSideEffect.send(UiSideEffect.OutOfTime)
}

viewModelScope.launch {
Expand Down Expand Up @@ -179,7 +180,7 @@ class ConnectViewModel(

fun onManageAccountClick() {
viewModelScope.launch {
_uiSideEffect.tryEmit(
_uiSideEffect.send(
UiSideEffect.OpenAccountManagementPageInBrowser(
serviceConnectionManager.authTokenCache()?.fetchAuthToken() ?: ""
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.onSubscription
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
Expand All @@ -35,8 +36,8 @@ class DeviceListViewModel(
) : ViewModel() {
private val _loadingDevices = MutableStateFlow<List<DeviceId>>(emptyList())

private val _uiSideEffect: MutableSharedFlow<DeviceListSideEffect> = MutableSharedFlow()
val uiSideEffect: SharedFlow<DeviceListSideEffect> = _uiSideEffect
private val _uiSideEffect = Channel<DeviceListSideEffect>(1, BufferOverflow.DROP_OLDEST)
val uiSideEffect = _uiSideEffect.receiveAsFlow()

private var cachedDeviceList: List<Device>? = null

Expand Down Expand Up @@ -85,7 +86,7 @@ class DeviceListViewModel(
clearLoadingDevice(deviceIdToRemove)

if (result == null) {
_uiSideEffect.emit(
_uiSideEffect.send(
DeviceListSideEffect.ShowToast(
resources.getString(R.string.failed_to_remove_device)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import androidx.lifecycle.viewModelScope
import java.net.InetAddress
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.constant.EMPTY_STRING
Expand Down Expand Up @@ -80,8 +81,8 @@ class DnsDialogViewModel(
createViewState(_ipAddressInput.value, vmState.value)
)

private val _uiSideEffect = MutableSharedFlow<DnsDialogSideEffect>()
val uiSideEffect: SharedFlow<DnsDialogSideEffect> = _uiSideEffect
private val _uiSideEffect = Channel<DnsDialogSideEffect>(1, BufferOverflow.DROP_OLDEST)
val uiSideEffect = _uiSideEffect.receiveAsFlow()

private fun createViewState(ipAddress: String, vmState: DnsDialogViewModelState) =
DnsDialogViewState(
Expand Down Expand Up @@ -126,15 +127,15 @@ class DnsDialogViewModel(
}
}

_uiSideEffect.emit(DnsDialogSideEffect.Complete)
_uiSideEffect.send(DnsDialogSideEffect.Complete)
}

fun onRemoveDnsClick() =
viewModelScope.launch(dispatcher) {
repository.updateCustomDnsList {
it.filter { it.hostAddress != uiState.value.ipAddress }
}
_uiSideEffect.emit(DnsDialogSideEffect.Complete)
_uiSideEffect.send(DnsDialogSideEffect.Complete)
}

private fun String.isValidIp(): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ package net.mullvad.mullvadvpn.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.compose.state.RelayFilterState
Expand All @@ -23,8 +24,8 @@ import net.mullvad.mullvadvpn.usecase.RelayListFilterUseCase
class FilterViewModel(
private val relayListFilterUseCase: RelayListFilterUseCase,
) : ViewModel() {
private val _uiSideEffect = MutableSharedFlow<FilterScreenSideEffect>()
val uiSideEffect = _uiSideEffect.asSharedFlow()
private val _uiSideEffect = Channel<FilterScreenSideEffect>(1, BufferOverflow.DROP_OLDEST)
val uiSideEffect = _uiSideEffect.receiveAsFlow()

private val selectedOwnership = MutableStateFlow<Ownership?>(null)
private val selectedProviders = MutableStateFlow<List<Provider>>(emptyList())
Expand Down Expand Up @@ -101,7 +102,7 @@ class FilterViewModel(
newSelectedOwnership,
newSelectedProviders
)
_uiSideEffect.emit(FilterScreenSideEffect.CloseScreen)
_uiSideEffect.send(FilterScreenSideEffect.CloseScreen)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -59,8 +59,8 @@ class LoginViewModel(
private val _loginState = MutableStateFlow(LoginUiState.INITIAL.loginState)
private val _loginInput = MutableStateFlow(LoginUiState.INITIAL.accountNumberInput)

private val _uiSideEffect = MutableSharedFlow<LoginUiSideEffect>(extraBufferCapacity = 1)
val uiSideEffect = _uiSideEffect.asSharedFlow()
private val _uiSideEffect = Channel<LoginUiSideEffect>(1, BufferOverflow.DROP_OLDEST)
val uiSideEffect = _uiSideEffect.receiveAsFlow()

private val _uiState =
combine(
Expand Down Expand Up @@ -112,9 +112,9 @@ class LoginViewModel(
delay(1000)
val isOutOfTime = isOutOfTimeDeferred.getOrDefault(false)
if (isOutOfTime) {
_uiSideEffect.emit(LoginUiSideEffect.NavigateToOutOfTime)
_uiSideEffect.send(LoginUiSideEffect.NavigateToOutOfTime)
} else {
_uiSideEffect.emit(LoginUiSideEffect.NavigateToConnect)
_uiSideEffect.send(LoginUiSideEffect.NavigateToConnect)
}
}
newDeviceNotificationUseCase.newDeviceCreated()
Expand All @@ -134,7 +134,7 @@ class LoginViewModel(
if (refreshResult.isAvailable()) {
// Navigate to device list

_uiSideEffect.emit(
_uiSideEffect.send(
LoginUiSideEffect.TooManyDevices(AccountToken(accountToken))
)
Idle()
Expand All @@ -157,7 +157,7 @@ class LoginViewModel(

private suspend fun AccountCreationResult.mapToUiState(): LoginState? {
return if (this is AccountCreationResult.Success) {
_uiSideEffect.emit(LoginUiSideEffect.NavigateToWelcome)
_uiSideEffect.send(LoginUiSideEffect.NavigateToWelcome)
null
} else {
Idle(LoginError.UnableToCreateAccount)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.repository.SettingsRepository
import net.mullvad.mullvadvpn.util.isValidMtu
Expand All @@ -15,21 +16,21 @@ class MtuDialogViewModel(
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
) : ViewModel() {

private val _uiSideEffect = MutableSharedFlow<MtuDialogSideEffect>()
val uiSideEffect: SharedFlow<MtuDialogSideEffect> = _uiSideEffect
private val _uiSideEffect = Channel<MtuDialogSideEffect>(1, BufferOverflow.DROP_OLDEST)
val uiSideEffect = _uiSideEffect.receiveAsFlow()

fun onSaveClick(mtuValue: Int) =
viewModelScope.launch(dispatcher) {
if (mtuValue.isValidMtu()) {
repository.setWireguardMtu(mtuValue)
}
_uiSideEffect.emit(MtuDialogSideEffect.Complete)
_uiSideEffect.send(MtuDialogSideEffect.Complete)
}

fun onRestoreClick() =
viewModelScope.launch(dispatcher) {
repository.setWireguardMtu(null)
_uiSideEffect.emit(MtuDialogSideEffect.Complete)
_uiSideEffect.send(MtuDialogSideEffect.Complete)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package net.mullvad.mullvadvpn.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
Expand Down Expand Up @@ -39,7 +40,11 @@ class OutOfTimeViewModel(
private val pollAccountExpiry: Boolean = true,
) : ViewModel() {

private val _uiSideEffect = MutableSharedFlow<UiSideEffect>(replay = 1)
private val _uiSideEffect =
MutableSharedFlow<UiSideEffect>(
extraBufferCapacity = 2,
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
val uiSideEffect = _uiSideEffect.asSharedFlow()

val uiState =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ package net.mullvad.mullvadvpn.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.repository.PrivacyDisclaimerRepository

class PrivacyDisclaimerViewModel(
private val privacyDisclaimerRepository: PrivacyDisclaimerRepository
) : ViewModel() {

private val _uiSideEffect =
MutableSharedFlow<PrivacyDisclaimerUiSideEffect>(extraBufferCapacity = 1)
val uiSideEffect = _uiSideEffect.asSharedFlow()
Channel<PrivacyDisclaimerUiSideEffect>(1, BufferOverflow.DROP_OLDEST)
val uiSideEffect = _uiSideEffect.receiveAsFlow()

fun setPrivacyDisclosureAccepted() {
privacyDisclaimerRepository.setPrivacyDisclosureAccepted()
viewModelScope.launch { _uiSideEffect.emit(PrivacyDisclaimerUiSideEffect.NavigateToLogin) }
viewModelScope.launch { _uiSideEffect.send(PrivacyDisclaimerUiSideEffect.NavigateToLogin) }
}
}

Expand Down
Loading

0 comments on commit 7e8d58f

Please sign in to comment.