Skip to content

Commit

Permalink
Align UseCases
Browse files Browse the repository at this point in the history
  • Loading branch information
Rawa authored and albin-mullvad committed Jun 18, 2024
1 parent bdfca5c commit ba23a45
Show file tree
Hide file tree
Showing 33 changed files with 120 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import net.mullvad.mullvadvpn.repository.ApiAccessRepository
import net.mullvad.mullvadvpn.repository.ChangelogRepository
import net.mullvad.mullvadvpn.repository.CustomListsRepository
import net.mullvad.mullvadvpn.repository.InAppNotificationController
import net.mullvad.mullvadvpn.repository.NewDeviceRepository
import net.mullvad.mullvadvpn.repository.PrivacyDisclaimerRepository
import net.mullvad.mullvadvpn.repository.ProblemReportRepository
import net.mullvad.mullvadvpn.repository.RelayListFilterRepository
Expand All @@ -30,16 +31,16 @@ import net.mullvad.mullvadvpn.ui.serviceconnection.AppVersionInfoRepository
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager
import net.mullvad.mullvadvpn.usecase.AccountExpiryNotificationUseCase
import net.mullvad.mullvadvpn.usecase.AvailableProvidersUseCase
import net.mullvad.mullvadvpn.usecase.ConnectivityUseCase
import net.mullvad.mullvadvpn.usecase.EmptyPaymentUseCase
import net.mullvad.mullvadvpn.usecase.FilteredRelayListUseCase
import net.mullvad.mullvadvpn.usecase.InternetAvailableUseCase
import net.mullvad.mullvadvpn.usecase.LastKnownLocationUseCase
import net.mullvad.mullvadvpn.usecase.NewDeviceNotificationUseCase
import net.mullvad.mullvadvpn.usecase.OutOfTimeUseCase
import net.mullvad.mullvadvpn.usecase.PaymentUseCase
import net.mullvad.mullvadvpn.usecase.PlayPaymentUseCase
import net.mullvad.mullvadvpn.usecase.SelectedLocationTitleUseCase
import net.mullvad.mullvadvpn.usecase.SystemVpnSettingsUseCase
import net.mullvad.mullvadvpn.usecase.SystemVpnSettingsAvailableUseCase
import net.mullvad.mullvadvpn.usecase.TunnelStateNotificationUseCase
import net.mullvad.mullvadvpn.usecase.VersionNotificationUseCase
import net.mullvad.mullvadvpn.usecase.customlists.CustomListActionUseCase
Expand Down Expand Up @@ -122,14 +123,15 @@ val uiModule = module {
single { VoucherRepository(get(), get()) }
single { SplitTunnelingRepository(get()) }
single { ApiAccessRepository(get()) }
single { NewDeviceRepository() }

single { AccountExpiryNotificationUseCase(get()) }
single { TunnelStateNotificationUseCase(get()) }
single { VersionNotificationUseCase(get(), BuildConfig.ENABLE_IN_APP_VERSION_NOTIFICATIONS) }
single { NewDeviceNotificationUseCase(get()) }
single { NewDeviceNotificationUseCase(get(), get()) }
single { OutOfTimeUseCase(get(), get(), MainScope()) }
single { ConnectivityUseCase(get()) }
single { SystemVpnSettingsUseCase(androidContext()) }
single { InternetAvailableUseCase(get()) }
single { SystemVpnSettingsAvailableUseCase(androidContext()) }
single { CustomListActionUseCase(get(), get()) }
single { SelectedLocationTitleUseCase(get(), get()) }
single { AvailableProvidersUseCase(get()) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,18 @@ sealed class InAppNotification {

class InAppNotificationController(
accountExpiryNotificationUseCase: AccountExpiryNotificationUseCase,
newDeviceNotificationUseCase: NewDeviceNotificationUseCase,
newDeviceNotificationUseRepository: NewDeviceNotificationUseCase,
versionNotificationUseCase: VersionNotificationUseCase,
tunnelStateNotificationUseCase: TunnelStateNotificationUseCase,
scope: CoroutineScope,
) {

val notifications =
combine(
tunnelStateNotificationUseCase.notifications(),
versionNotificationUseCase.notifications(),
accountExpiryNotificationUseCase.notifications(),
newDeviceNotificationUseCase.notifications(),
tunnelStateNotificationUseCase(),
versionNotificationUseCase(),
accountExpiryNotificationUseCase(),
newDeviceNotificationUseRepository(),
) { a, b, c, d ->
a + b + c + d
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package net.mullvad.mullvadvpn.repository

import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

class NewDeviceRepository {
private val _mutableShowNewDeviceNotification = MutableStateFlow(false)

val isNewDevice: StateFlow<Boolean> = _mutableShowNewDeviceNotification

fun newDeviceCreated() {
_mutableShowNewDeviceNotification.value = true
}

fun clearNewDeviceCreatedNotification() {
_mutableShowNewDeviceNotification.value = false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import org.joda.time.DateTime
class AccountExpiryNotificationUseCase(
private val accountRepository: AccountRepository,
) {
fun notifications(): Flow<List<InAppNotification>> =
operator fun invoke(): Flow<List<InAppNotification>> =
accountRepository.accountData
.map(::accountExpiryNotification)
.map(::listOfNotNull)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import net.mullvad.mullvadvpn.repository.RelayListRepository

class AvailableProvidersUseCase(private val relayListRepository: RelayListRepository) {

fun availableProviders(): Flow<List<Provider>> =
operator fun invoke(): Flow<List<Provider>> =
relayListRepository.relayList.map { relayList ->
relayList
.flatMap(RelayItem.Location.Country::cities)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class FilteredRelayListUseCase(
private val relayListRepository: RelayListRepository,
private val relayListFilterRepository: RelayListFilterRepository
) {
fun filteredRelayList() =
operator fun invoke() =
combine(
relayListRepository.relayList,
relayListFilterRepository.selectedOwnership,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities

class ConnectivityUseCase(val context: Context) {
fun isInternetAvailable(): Boolean {
class InternetAvailableUseCase(val context: Context) {
operator fun invoke(): Boolean {
val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,25 @@
package net.mullvad.mullvadvpn.usecase

import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import net.mullvad.mullvadvpn.lib.shared.DeviceRepository
import net.mullvad.mullvadvpn.repository.InAppNotification
import net.mullvad.mullvadvpn.repository.NewDeviceRepository

class NewDeviceNotificationUseCase(private val deviceRepository: DeviceRepository) {
private val _mutableShowNewDeviceNotification = MutableStateFlow(false)

fun notifications() =
class NewDeviceNotificationUseCase(
private val newDeviceRepository: NewDeviceRepository,
private val deviceRepository: DeviceRepository
) {
operator fun invoke() =
combine(
deviceRepository.deviceState.map { it?.displayName() },
_mutableShowNewDeviceNotification
newDeviceRepository.isNewDevice
) { deviceName, newDeviceCreated ->
if (newDeviceCreated && deviceName != null) {
InAppNotification.NewDevice(deviceName)
} else null
}
.map(::listOfNotNull)
.distinctUntilChanged()

fun newDeviceCreated() {
_mutableShowNewDeviceNotification.value = true
}

fun clearNewDeviceCreatedNotification() {
_mutableShowNewDeviceNotification.value = false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class PlayPaymentUseCase(private val paymentRepository: PaymentRepository) : Pay
override val paymentAvailability = _paymentAvailability.asStateFlow()
override val purchaseResult = _purchaseResult.asStateFlow()

@Suppress("ensure every public functions method is named 'invoke' with operator modifier")
override suspend fun purchaseProduct(productId: ProductId, activityProvider: () -> Activity) {
paymentRepository
.purchaseProduct(productId, activityProvider)
Expand All @@ -48,14 +49,17 @@ class PlayPaymentUseCase(private val paymentRepository: PaymentRepository) : Pay
.collect(_purchaseResult)
}

@Suppress("ensure every public functions method is named 'invoke' with operator modifier")
override suspend fun queryPaymentAvailability() {
paymentRepository.queryPaymentAvailability().collect(_paymentAvailability)
}

@Suppress("ensure every public functions method is named 'invoke' with operator modifier")
override suspend fun resetPurchaseResult() {
_purchaseResult.emit(null)
}

@Suppress("ensure every public functions method is named 'invoke' with operator modifier")
override suspend fun verifyPurchases(onSuccessfulVerification: () -> Unit) {
paymentRepository
.verifyPurchases()
Expand Down Expand Up @@ -87,18 +91,22 @@ class EmptyPaymentUseCase : PaymentUseCase {
override val paymentAvailability = MutableStateFlow(PaymentAvailability.ProductsUnavailable)
override val purchaseResult = MutableStateFlow<PurchaseResult?>(null)

@Suppress("ensure every public functions method is named 'invoke' with operator modifier")
override suspend fun purchaseProduct(productId: ProductId, activityProvider: () -> Activity) {
// No op
}

@Suppress("ensure every public functions method is named 'invoke' with operator modifier")
override suspend fun queryPaymentAvailability() {
// No op
}

@Suppress("ensure every public functions method is named 'invoke' with operator modifier")
override suspend fun resetPurchaseResult() {
// No op
}

@Suppress("ensure every public functions method is named 'invoke' with operator modifier")
override suspend fun verifyPurchases(onSuccessfulVerification: () -> Unit) {
// No op
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class SelectedLocationTitleUseCase(
private val customListsRepository: CustomListsRepository,
private val relayListRepository: RelayListRepository,
) {
fun selectedLocationTitle() =
operator fun invoke() =
combine(
customListsRepository.customLists,
relayListRepository.relayList,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package net.mullvad.mullvadvpn.usecase
import android.content.Context
import android.content.Intent

class SystemVpnSettingsUseCase(val context: Context) {
fun systemVpnSettingsAvailable(): Boolean =
class SystemVpnSettingsAvailableUseCase(val context: Context) {
operator fun invoke(): Boolean =
Intent("android.net.vpn.SETTINGS").resolveActivity(context.packageManager) != null
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import net.mullvad.mullvadvpn.lib.shared.ConnectionProxy
import net.mullvad.mullvadvpn.repository.InAppNotification

class TunnelStateNotificationUseCase(private val connectionProxy: ConnectionProxy) {
fun notifications(): Flow<List<InAppNotification>> =
operator fun invoke(): Flow<List<InAppNotification>> =
connectionProxy.tunnelState
.distinctUntilChanged()
.map(::tunnelStateNotification)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class VersionNotificationUseCase(
private val isVersionInfoNotificationEnabled: Boolean,
) {

fun notifications() =
operator fun invoke() =
appVersionInfoRepository
.versionInfo()
.map { versionInfo ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,32 @@ class CustomListActionUseCase(
private val customListsRepository: CustomListsRepository,
private val relayListRepository: RelayListRepository
) {
suspend fun performAction(
suspend operator fun invoke(
action: CustomListAction
): Either<CustomListActionError, CustomListSuccess> {
return when (action) {
is CustomListAction.Create -> {
performAction(action)
invoke(action)
}
is CustomListAction.Rename -> {
performAction(action)
invoke(action)
}
is CustomListAction.Delete -> {
performAction(action)
invoke(action)
}
is CustomListAction.UpdateLocations -> {
performAction(action)
invoke(action)
}
}
}

suspend fun performAction(action: CustomListAction.Rename): Either<RenameError, Renamed> =
suspend operator fun invoke(action: CustomListAction.Rename): Either<RenameError, Renamed> =
customListsRepository
.updateCustomListName(action.id, action.newName)
.map { Renamed(undo = action.not()) }
.mapLeft(::RenameError)

suspend fun performAction(
suspend operator fun invoke(
action: CustomListAction.Create
): Either<CreateWithLocationsError, Created> = either {
val customListId =
Expand Down Expand Up @@ -79,7 +79,7 @@ class CustomListActionUseCase(
)
}

suspend fun performAction(
suspend operator fun invoke(
action: CustomListAction.Delete
): Either<DeleteWithUndoError, Deleted> = either {
val customList =
Expand All @@ -94,7 +94,7 @@ class CustomListActionUseCase(
Deleted(undo = action.not(locations = customList.locations, name = customList.name))
}

suspend fun performAction(
suspend operator fun invoke(
action: CustomListAction.UpdateLocations
): Either<UpdateLocationsError, LocationsChanged> = either {
val customList =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ class CustomListRelayItemsUseCase(
private val customListsRepository: CustomListsRepository,
private val relayListRepository: RelayListRepository
) {
fun getRelayItemLocationsForCustomList(
customListId: CustomListId
): Flow<List<RelayItem.Location>> =
operator fun invoke(customListId: CustomListId): Flow<List<RelayItem.Location>> =
combine(
customListsRepository.customLists.mapNotNull { it?.getById(customListId) },
relayListRepository.relayList
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class CustomListsRelayItemUseCase(
private val relayListRepository: RelayListRepository,
) {

fun relayItemCustomLists() =
operator fun invoke() =
combine(customListsRepository.customLists, relayListRepository.relayList) {
customLists,
relayList ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import net.mullvad.mullvadvpn.lib.shared.ConnectionProxy
import net.mullvad.mullvadvpn.lib.shared.DeviceRepository
import net.mullvad.mullvadvpn.lib.shared.VpnPermissionRepository
import net.mullvad.mullvadvpn.repository.InAppNotificationController
import net.mullvad.mullvadvpn.repository.NewDeviceRepository
import net.mullvad.mullvadvpn.usecase.LastKnownLocationUseCase
import net.mullvad.mullvadvpn.usecase.NewDeviceNotificationUseCase
import net.mullvad.mullvadvpn.usecase.OutOfTimeUseCase
import net.mullvad.mullvadvpn.usecase.PaymentUseCase
import net.mullvad.mullvadvpn.usecase.SelectedLocationTitleUseCase
Expand All @@ -40,7 +40,7 @@ class ConnectViewModel(
private val accountRepository: AccountRepository,
private val deviceRepository: DeviceRepository,
inAppNotificationController: InAppNotificationController,
private val newDeviceNotificationUseCase: NewDeviceNotificationUseCase,
private val newDeviceRepository: NewDeviceRepository,
selectedLocationTitleUseCase: SelectedLocationTitleUseCase,
private val outOfTimeUseCase: OutOfTimeUseCase,
private val paymentUseCase: PaymentUseCase,
Expand All @@ -57,7 +57,7 @@ class ConnectViewModel(
@OptIn(FlowPreview::class)
val uiState: StateFlow<ConnectUiState> =
combine(
selectedLocationTitleUseCase.selectedLocationTitle(),
selectedLocationTitleUseCase(),
inAppNotificationController.notifications,
connectionProxy.tunnelState,
lastKnownLocationUseCase.lastKnownDisconnectedLocation,
Expand Down Expand Up @@ -167,7 +167,7 @@ class ConnectViewModel(
}

fun dismissNewDeviceNotification() {
newDeviceNotificationUseCase.clearNewDeviceCreatedNotification()
newDeviceRepository.clearNewDeviceCreatedNotification()
}

private fun outOfTimeEffect() =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ class CreateCustomListDialogViewModel(

fun createCustomList(name: String) {
viewModelScope.launch {
customListActionUseCase
.performAction(
customListActionUseCase(
CustomListAction.Create(
CustomListName.fromString(name),
listOfNotNull(locationCode)
Expand Down
Loading

0 comments on commit ba23a45

Please sign in to comment.