mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-07 21:37:02 +09:00
DROID-3629 Onboarding | Local mode status (#2400)
This commit is contained in:
parent
a52bd6f4ae
commit
9da4bc43b7
12 changed files with 212 additions and 20 deletions
|
@ -6,6 +6,8 @@ import com.anytypeio.anytype.di.common.ComponentDependencies
|
|||
import com.anytypeio.anytype.domain.auth.interactor.GetMnemonic
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
import com.anytypeio.anytype.domain.config.ConfigStorage
|
||||
import com.anytypeio.anytype.domain.device.NetworkConnectionStatus
|
||||
import com.anytypeio.anytype.domain.network.NetworkModeProvider
|
||||
import com.anytypeio.anytype.presentation.onboarding.signup.OnboardingMnemonicViewModel
|
||||
import dagger.Binds
|
||||
import dagger.Component
|
||||
|
@ -57,6 +59,8 @@ interface OnboardingMnemonicDependencies : ComponentDependencies {
|
|||
fun authRepository(): AuthRepository
|
||||
fun analytics(): Analytics
|
||||
fun config(): ConfigStorage
|
||||
fun networkModeProvider(): NetworkModeProvider
|
||||
fun networkConnectionStatus(): NetworkConnectionStatus
|
||||
}
|
||||
|
||||
@Scope
|
||||
|
|
|
@ -2,8 +2,6 @@ package com.anytypeio.anytype.di.main
|
|||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.security.crypto.EncryptedSharedPreferences
|
||||
import androidx.security.crypto.MasterKeys
|
||||
import com.anytypeio.anytype.app.DefaultAppActionManager
|
||||
import com.anytypeio.anytype.app.DefaultInitialParamsProvider
|
||||
import com.anytypeio.anytype.core_utils.tools.ThreadInfo
|
||||
|
@ -49,10 +47,10 @@ import com.anytypeio.anytype.middleware.interactor.ProtobufConverterProvider
|
|||
import com.anytypeio.anytype.middleware.service.MiddlewareService
|
||||
import com.anytypeio.anytype.middleware.service.MiddlewareServiceImplementation
|
||||
import com.anytypeio.anytype.persistence.db.AnytypeDatabase
|
||||
import com.anytypeio.anytype.persistence.networkmode.NetworkModeProvider
|
||||
import com.anytypeio.anytype.device.providers.AppDefaultDateFormatProvider
|
||||
import com.anytypeio.anytype.device.providers.AppDefaultDateFormatProviderImpl
|
||||
import com.anytypeio.anytype.domain.misc.LocaleProvider
|
||||
import com.anytypeio.anytype.domain.network.NetworkModeProvider
|
||||
import com.anytypeio.anytype.persistence.repo.DefaultAuthCache
|
||||
import com.anytypeio.anytype.persistence.repo.DefaultDebugSettingsCache
|
||||
import com.anytypeio.anytype.persistence.repo.DefaultUserSettingsCache
|
||||
|
@ -62,10 +60,8 @@ import com.anytypeio.anytype.security.KeystoreManager
|
|||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import java.security.GeneralSecurityException
|
||||
import javax.inject.Named
|
||||
import javax.inject.Singleton
|
||||
import timber.log.Timber
|
||||
|
||||
@Module(includes = [DataModule.Bindings::class])
|
||||
object DataModule {
|
||||
|
|
|
@ -7,9 +7,9 @@ import com.anytypeio.anytype.device.network_type.NetworkConnectionStatusImpl
|
|||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
import com.anytypeio.anytype.domain.device.NetworkConnectionStatus
|
||||
import com.anytypeio.anytype.domain.network.NetworkModeProvider
|
||||
import com.anytypeio.anytype.persistence.networkmode.DefaultNetworkModeProvider
|
||||
import com.anytypeio.anytype.persistence.networkmode.DefaultNetworkModeProvider.NetworkModeConstants.NAMED_NETWORK_MODE_PREFS
|
||||
import com.anytypeio.anytype.persistence.networkmode.NetworkModeProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import javax.inject.Named
|
||||
|
|
|
@ -24,6 +24,8 @@ class NetworkConnectionStatusImpl(
|
|||
context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
|
||||
private var isMonitoring = false
|
||||
|
||||
private var currentNetworkType: DeviceNetworkType = DeviceNetworkType.NOT_CONNECTED
|
||||
|
||||
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
|
||||
override fun onAvailable(network: Network) {
|
||||
// Called when the network is available
|
||||
|
@ -74,6 +76,7 @@ class NetworkConnectionStatusImpl(
|
|||
private fun updateNetworkState(networkCapabilities: NetworkCapabilities?) {
|
||||
coroutineScope.launch {
|
||||
val networkType = mapNetworkType(networkCapabilities)
|
||||
currentNetworkType = networkType
|
||||
withContext(dispatchers.io) {
|
||||
try {
|
||||
blockRepository.setDeviceNetworkState(networkType)
|
||||
|
@ -102,4 +105,11 @@ class NetworkConnectionStatusImpl(
|
|||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> DeviceNetworkType.CELLULAR
|
||||
else -> DeviceNetworkType.NOT_CONNECTED
|
||||
}
|
||||
|
||||
override fun getCurrentNetworkType(): DeviceNetworkType {
|
||||
if (!isMonitoring) {
|
||||
return mapNetworkType(getNetworkCapabilities())
|
||||
}
|
||||
return currentNetworkType
|
||||
}
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
package com.anytypeio.anytype.domain.device
|
||||
|
||||
import com.anytypeio.anytype.core_models.DeviceNetworkType
|
||||
|
||||
interface NetworkConnectionStatus {
|
||||
fun start()
|
||||
fun stop()
|
||||
fun getCurrentNetworkType(): DeviceNetworkType
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.anytypeio.anytype.domain.network
|
||||
|
||||
import com.anytypeio.anytype.core_models.NetworkModeConfig
|
||||
|
||||
/**
|
||||
* Interface for providing and managing network mode configuration
|
||||
*/
|
||||
interface NetworkModeProvider {
|
||||
/**
|
||||
* Set a new network mode configuration
|
||||
* @param networkModeConfig The network mode configuration to set
|
||||
*/
|
||||
fun set(networkModeConfig: NetworkModeConfig)
|
||||
|
||||
/**
|
||||
* Get the current network mode configuration
|
||||
* @return The current NetworkModeConfig
|
||||
*/
|
||||
fun get(): NetworkModeConfig
|
||||
|
||||
/**
|
||||
* Clear the current network mode configuration
|
||||
*/
|
||||
fun clear()
|
||||
}
|
|
@ -11,6 +11,7 @@ dependencies {
|
|||
implementation project(':data')
|
||||
implementation project(':core-models')
|
||||
implementation project(':device')
|
||||
implementation project(':domain')
|
||||
|
||||
implementation libs.kotlin
|
||||
implementation libs.coroutinesAndroid
|
||||
|
|
|
@ -6,17 +6,12 @@ import com.anytypeio.anytype.core_models.NetworkModeConfig
|
|||
import com.anytypeio.anytype.core_models.NetworkModeConstants.NETWORK_MODE_CUSTOM
|
||||
import com.anytypeio.anytype.core_models.NetworkModeConstants.NETWORK_MODE_DEFAULT
|
||||
import com.anytypeio.anytype.core_models.NetworkModeConstants.NETWORK_MODE_LOCAL
|
||||
import com.anytypeio.anytype.domain.network.NetworkModeProvider
|
||||
import com.anytypeio.anytype.persistence.networkmode.DefaultNetworkModeProvider.NetworkModeConstants.NETWORK_MODE_APP_FILE_PATH_PREF
|
||||
import com.anytypeio.anytype.persistence.networkmode.DefaultNetworkModeProvider.NetworkModeConstants.NETWORK_MODE_PREF
|
||||
import com.anytypeio.anytype.persistence.networkmode.DefaultNetworkModeProvider.NetworkModeConstants.NETWORK_MODE_USER_FILE_PATH_PREF
|
||||
import com.anytypeio.anytype.persistence.networkmode.DefaultNetworkModeProvider.NetworkModeConstants.USE_RESERVE_MULTIPLEX_LIBRARY_PREF
|
||||
|
||||
interface NetworkModeProvider {
|
||||
fun set(networkModeConfig: NetworkModeConfig)
|
||||
fun get(): NetworkModeConfig
|
||||
fun clear()
|
||||
}
|
||||
|
||||
class DefaultNetworkModeProvider(private val sharedPreferences: SharedPreferences) :
|
||||
NetworkModeProvider {
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ import android.content.SharedPreferences
|
|||
import com.anytypeio.anytype.core_models.NetworkModeConfig
|
||||
import com.anytypeio.anytype.data.auth.model.AccountEntity
|
||||
import com.anytypeio.anytype.data.auth.repo.AuthCache
|
||||
import com.anytypeio.anytype.domain.network.NetworkModeProvider
|
||||
import com.anytypeio.anytype.persistence.db.AnytypeDatabase
|
||||
import com.anytypeio.anytype.persistence.mapper.toEntity
|
||||
import com.anytypeio.anytype.persistence.mapper.toTable
|
||||
import com.anytypeio.anytype.persistence.networkmode.NetworkModeProvider
|
||||
|
||||
class DefaultAuthCache(
|
||||
private val db: AnytypeDatabase,
|
||||
|
|
|
@ -4,9 +4,9 @@ import android.content.Context
|
|||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import androidx.room.Room
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.anytypeio.anytype.domain.network.NetworkModeProvider
|
||||
import com.anytypeio.anytype.persistence.db.AnytypeDatabase
|
||||
import com.anytypeio.anytype.persistence.networkmode.DefaultNetworkModeProvider
|
||||
import com.anytypeio.anytype.persistence.networkmode.NetworkModeProvider
|
||||
import com.anytypeio.anytype.persistence.repo.DefaultAuthCache
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
import kotlin.test.assertEquals
|
||||
|
|
|
@ -5,11 +5,14 @@ import androidx.lifecycle.ViewModelProvider
|
|||
import androidx.lifecycle.viewModelScope
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary
|
||||
import com.anytypeio.anytype.core_models.DeviceNetworkType
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.NetworkModeConfig
|
||||
import com.anytypeio.anytype.core_models.NetworkMode
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.domain.auth.interactor.GetMnemonic
|
||||
import com.anytypeio.anytype.domain.config.ConfigStorage
|
||||
import com.anytypeio.anytype.domain.device.NetworkConnectionStatus
|
||||
import com.anytypeio.anytype.domain.network.NetworkModeProvider
|
||||
import com.anytypeio.anytype.presentation.extension.sendAnalyticsOnboardingClickEvent
|
||||
import com.anytypeio.anytype.presentation.extension.sendAnalyticsOnboardingScreenEvent
|
||||
import com.anytypeio.anytype.presentation.extension.sendOpenAccountEvent
|
||||
|
@ -22,7 +25,9 @@ import timber.log.Timber
|
|||
class OnboardingMnemonicViewModel @Inject constructor(
|
||||
private val getMnemonic: GetMnemonic,
|
||||
private val analytics: Analytics,
|
||||
private val configStorage: ConfigStorage
|
||||
private val configStorage: ConfigStorage,
|
||||
private val networkModeProvider: NetworkModeProvider,
|
||||
private val networkConnectionStatus: NetworkConnectionStatus
|
||||
) : ViewModel() {
|
||||
|
||||
val state = MutableStateFlow<State>(State.Idle(""))
|
||||
|
@ -128,9 +133,13 @@ class OnboardingMnemonicViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun shouldShowEmail(): Boolean {
|
||||
//todo: update with Local Only config
|
||||
return true
|
||||
fun shouldShowEmail(): Boolean {
|
||||
val networkStatus = networkConnectionStatus.getCurrentNetworkType()
|
||||
if (networkStatus == DeviceNetworkType.NOT_CONNECTED) {
|
||||
Timber.i("Network is not connected, skipping email screen")
|
||||
return false
|
||||
}
|
||||
return networkModeProvider.get().networkMode != NetworkMode.LOCAL
|
||||
}
|
||||
|
||||
private suspend fun proceedWithMnemonicPhrase() {
|
||||
|
@ -156,13 +165,17 @@ class OnboardingMnemonicViewModel @Inject constructor(
|
|||
private val getMnemonic: GetMnemonic,
|
||||
private val analytics: Analytics,
|
||||
private val configStorage: ConfigStorage,
|
||||
private val networkModeProvider: NetworkModeProvider,
|
||||
private val networkConnectionStatus: NetworkConnectionStatus
|
||||
) : ViewModelProvider.Factory {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return OnboardingMnemonicViewModel(
|
||||
getMnemonic = getMnemonic,
|
||||
analytics = analytics,
|
||||
configStorage = configStorage
|
||||
configStorage = configStorage,
|
||||
networkModeProvider = networkModeProvider,
|
||||
networkConnectionStatus = networkConnectionStatus
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
package com.anytypeio.anytype.presentation.onboarding.signup
|
||||
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_models.DeviceNetworkType
|
||||
import com.anytypeio.anytype.core_models.NetworkMode
|
||||
import com.anytypeio.anytype.core_models.NetworkModeConfig
|
||||
import com.anytypeio.anytype.domain.auth.interactor.GetMnemonic
|
||||
import com.anytypeio.anytype.domain.config.ConfigStorage
|
||||
import com.anytypeio.anytype.domain.device.NetworkConnectionStatus
|
||||
import com.anytypeio.anytype.domain.network.NetworkModeProvider
|
||||
import com.anytypeio.anytype.presentation.util.DefaultCoroutineTestRule
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.kotlin.stub
|
||||
|
||||
class OnboardingMnemonicViewModelTest {
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@get:Rule
|
||||
val coroutineTestRule = DefaultCoroutineTestRule()
|
||||
|
||||
@Mock
|
||||
private lateinit var getMnemonic: GetMnemonic
|
||||
|
||||
@Mock
|
||||
private lateinit var analytics: Analytics
|
||||
|
||||
@Mock
|
||||
private lateinit var configStorage: ConfigStorage
|
||||
|
||||
@Mock
|
||||
private lateinit var networkConnectionStatus: NetworkConnectionStatus
|
||||
|
||||
@Mock
|
||||
private lateinit var networkModeProvider: NetworkModeProvider
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
MockitoAnnotations.openMocks(this)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `shouldShowEmail returns false when network is not connected`() {
|
||||
// Given
|
||||
networkConnectionStatus.stub {
|
||||
on { getCurrentNetworkType() }.thenReturn(DeviceNetworkType.NOT_CONNECTED)
|
||||
}
|
||||
networkModeProvider.stub {
|
||||
on { get() }.thenReturn(
|
||||
NetworkModeConfig(
|
||||
networkMode = NetworkMode.DEFAULT
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// When
|
||||
val viewModel = createViewModel()
|
||||
val result = viewModel.shouldShowEmail()
|
||||
|
||||
// Then
|
||||
assertFalse(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `shouldShowEmail returns false when network mode is LOCAL`() {
|
||||
// Given
|
||||
networkConnectionStatus.stub {
|
||||
on { getCurrentNetworkType() }.thenReturn(DeviceNetworkType.WIFI)
|
||||
}
|
||||
networkModeProvider.stub {
|
||||
on { get() }.thenReturn(
|
||||
NetworkModeConfig(
|
||||
networkMode = NetworkMode.LOCAL
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// When
|
||||
val viewModel = createViewModel()
|
||||
val result = viewModel.shouldShowEmail()
|
||||
|
||||
// Then
|
||||
assertFalse(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `shouldShowEmail returns true when connected to network and network mode is not LOCAL`() {
|
||||
// Given
|
||||
networkConnectionStatus.stub {
|
||||
on { getCurrentNetworkType() }.thenReturn(DeviceNetworkType.WIFI)
|
||||
}
|
||||
networkModeProvider.stub {
|
||||
on { get() }.thenReturn(
|
||||
NetworkModeConfig(
|
||||
networkMode = NetworkMode.DEFAULT
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// When
|
||||
val viewModel = createViewModel()
|
||||
val result = viewModel.shouldShowEmail()
|
||||
|
||||
// Then
|
||||
assertTrue(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `shouldShowEmail returns true with cellular network and non-LOCAL mode`() {
|
||||
// Given
|
||||
networkConnectionStatus.stub {
|
||||
on { getCurrentNetworkType() }.thenReturn(DeviceNetworkType.CELLULAR)
|
||||
}
|
||||
networkModeProvider.stub {
|
||||
on { get() }.thenReturn(
|
||||
NetworkModeConfig(
|
||||
networkMode = NetworkMode.DEFAULT
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// When
|
||||
val viewModel = createViewModel()
|
||||
val result = viewModel.shouldShowEmail()
|
||||
|
||||
// Then
|
||||
assertTrue(result)
|
||||
}
|
||||
|
||||
private fun createViewModel(): OnboardingMnemonicViewModel {
|
||||
return OnboardingMnemonicViewModel(
|
||||
getMnemonic = getMnemonic,
|
||||
analytics = analytics,
|
||||
configStorage = configStorage,
|
||||
networkModeProvider = networkModeProvider,
|
||||
networkConnectionStatus = networkConnectionStatus
|
||||
)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue