Scopes the service manager into the AccountState ViewModel

This commit is contained in:
Vitor Pamplona
2023-11-29 09:14:04 -05:00
parent a85ea70e4f
commit 0dabf3f2d3
3 changed files with 48 additions and 48 deletions
@@ -75,11 +75,11 @@ class MainActivity : AppCompatActivity() {
LaunchedEffect(key1 = sharedPreferencesViewModel) {
sharedPreferencesViewModel.init()
sharedPreferencesViewModel.updateDisplaySettings(windowSizeClass, displayFeatures)
}
LaunchedEffect(isOnMobileDataState) {
sharedPreferencesViewModel.updateConnectivityStatusState(isOnMobileDataState)
sharedPreferencesViewModel.updateDisplaySettings(windowSizeClass, displayFeatures)
}
AmethystTheme(sharedPreferencesViewModel) {
@@ -89,12 +89,13 @@ class MainActivity : AppCompatActivity() {
color = MaterialTheme.colorScheme.background
) {
val accountStateViewModel: AccountStateViewModel = viewModel()
accountStateViewModel.serviceManager = serviceManager
LaunchedEffect(key1 = Unit) {
accountStateViewModel.tryLoginExistingAccountAsync()
}
AccountScreen(accountStateViewModel, sharedPreferencesViewModel, serviceManager)
AccountScreen(accountStateViewModel, sharedPreferencesViewModel)
}
}
}
@@ -125,7 +126,10 @@ class MainActivity : AppCompatActivity() {
PushNotificationUtils.init(LocalPreferences.allSavedAccounts())
}
(getSystemService(ConnectivityManager::class.java) as ConnectivityManager).registerDefaultNetworkCallback(networkCallback)
val connectivityManager = (getSystemService(ConnectivityManager::class.java) as ConnectivityManager)
connectivityManager.registerDefaultNetworkCallback(networkCallback)
connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
?.let { updateNetworkCapabilities(it) }
// resets state until next External Signer Call
Timer().schedule(350) {
@@ -200,17 +204,42 @@ class MainActivity : AppCompatActivity() {
}
}
fun updateNetworkCapabilities(networkCapabilities: NetworkCapabilities): Boolean {
val isOnMobileData = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
val isOnWifi = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
var changedNetwork = false
if (isOnMobileDataState.value != isOnMobileData) {
isOnMobileDataState.value = isOnMobileData
changedNetwork = true
}
if (isOnWifiDataState.value != isOnWifi) {
isOnWifiDataState.value = isOnWifi
changedNetwork = true
}
return changedNetwork
}
@OptIn(DelicateCoroutinesApi::class)
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
var lastNetwork: Network? = null
override fun onAvailable(network: Network) {
super.onAvailable(network)
Log.d("shouldPauseService", "shouldPauseService onAvailable: $shouldPauseService")
if (shouldPauseService) {
Log.d("ServiceManager NetworkCallback", "onAvailable: $shouldPauseService")
if (shouldPauseService && lastNetwork != null && lastNetwork != network) {
GlobalScope.launch(Dispatchers.IO) {
serviceManager.forceRestart()
}
}
lastNetwork = network
}
// Network capabilities have changed for the network
@@ -221,26 +250,8 @@ class MainActivity : AppCompatActivity() {
super.onCapabilitiesChanged(network, networkCapabilities)
GlobalScope.launch(Dispatchers.IO) {
val isOnMobileData = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
val isOnWifi = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
Log.d("ServiceManager NetworkCallback", "onCapabilitiesChanged: ${network.networkHandle} hasMobileData $isOnMobileData hasWifi $isOnWifi")
var changedNetwork = false
if (isOnMobileDataState.value != isOnMobileData) {
isOnMobileDataState.value = isOnMobileData
changedNetwork = true
}
if (isOnWifiDataState.value != isOnWifi) {
isOnWifiDataState.value = isOnWifi
changedNetwork = true
}
Log.d("shouldPauseService", "shouldPauseService onCapabilitiesChanged: $shouldPauseService")
if (changedNetwork && shouldPauseService) {
Log.d("ServiceManager NetworkCallback", "onCapabilitiesChanged: ${network.networkHandle} hasMobileData ${isOnMobileDataState.value} hasWifi ${isOnWifiDataState.value}")
if (updateNetworkCapabilities(networkCapabilities) && shouldPauseService) {
GlobalScope.launch(Dispatchers.IO) {
serviceManager.forceRestart()
}
@@ -14,7 +14,6 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -26,7 +25,6 @@ import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.Amethyst
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ServiceManager
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.ui.MainActivity
import com.vitorpamplona.amethyst.ui.components.getActivity
@@ -34,14 +32,12 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.MainScreen
import com.vitorpamplona.amethyst.ui.screen.loggedOff.LoginPage
import com.vitorpamplona.quartz.signers.NostrSignerExternal
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@Composable
fun AccountScreen(
accountStateViewModel: AccountStateViewModel,
sharedPreferencesViewModel: SharedPreferencesViewModel,
serviceManager: ServiceManager
sharedPreferencesViewModel: SharedPreferencesViewModel
) {
val accountState by accountStateViewModel.accountContent.collectAsStateWithLifecycle()
@@ -55,21 +51,9 @@ fun AccountScreen(
LoadingAccounts()
}
is AccountState.LoggedOff -> {
LaunchedEffect(key1 = state) {
launch(Dispatchers.IO) {
serviceManager.pauseForGood()
}
}
LoginPage(accountStateViewModel, isFirstLogin = true)
}
is AccountState.LoggedIn -> {
LaunchedEffect(key1 = state) {
launch(Dispatchers.IO) {
serviceManager.restartIfDifferentAccount(state.account)
}
}
CompositionLocalProvider(
LocalViewModelStoreOwner provides state.currentViewModelStore
) {
@@ -81,12 +65,6 @@ fun AccountScreen(
}
}
is AccountState.LoggedInViewOnly -> {
LaunchedEffect(key1 = state) {
launch(Dispatchers.IO) {
serviceManager.restartIfDifferentAccount(state.account)
}
}
CompositionLocalProvider(
LocalViewModelStoreOwner provides state.currentViewModelStore
) {
@@ -6,6 +6,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.vitorpamplona.amethyst.AccountInfo
import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.ServiceManager
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.service.HttpClient
import com.vitorpamplona.quartz.crypto.KeyPair
@@ -32,6 +33,8 @@ val EMAIL_PATTERN = Pattern.compile(".+@.+\\.[a-z]+")
@Stable
class AccountStateViewModel() : ViewModel() {
var serviceManager: ServiceManager? = null
private val _accountContent = MutableStateFlow<AccountState>(AccountState.Loading)
val accountContent = _accountContent.asStateFlow()
@@ -52,6 +55,10 @@ class AccountStateViewModel() : ViewModel() {
private suspend fun requestLoginUI() {
_accountContent.update { AccountState.LoggedOff }
viewModelScope.launch(Dispatchers.IO) {
serviceManager?.pauseForGood()
}
}
suspend fun loginAndStartUI(
@@ -101,6 +108,10 @@ class AccountStateViewModel() : ViewModel() {
_accountContent.update { AccountState.LoggedInViewOnly(account) }
}
viewModelScope.launch(Dispatchers.IO) {
serviceManager?.restartIfDifferentAccount(account)
}
account.saveable.observeForever(saveListener)
}