diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ServiceManager.kt b/app/src/main/java/com/vitorpamplona/amethyst/ServiceManager.kt index 414ba56d3..bdcb1f5c4 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ServiceManager.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ServiceManager.kt @@ -1,14 +1,11 @@ package com.vitorpamplona.amethyst -import android.content.Context import android.os.Build import android.util.Log import coil.Coil import coil.decode.GifDecoder import coil.decode.ImageDecoderDecoder import coil.decode.SvgDecoder -import coil.disk.DiskCache -import coil.util.DebugLogger import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.service.ExternalSignerUtils @@ -36,9 +33,8 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import java.io.File -object ServiceManager { +class ServiceManager { var shouldPauseService: Boolean = true // to not open amber in a loop trying to use auth relays and registering for notifications private var isStarted: Boolean = false // to not open amber in a loop trying to use auth relays and registering for notifications private var account: Account? = null @@ -69,7 +65,7 @@ object ServiceManager { add(GifDecoder.Factory()) } add(SvgDecoder.Factory()) - }.logger(DebugLogger()) + } // .logger(DebugLogger()) .okHttpClient { HttpClient.getHttpClient() } .respectCacheHeaders(false) .build() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt index 7e3733db9..7110b2ada 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt @@ -54,6 +54,9 @@ import java.nio.charset.StandardCharsets class MainActivity : AppCompatActivity() { private val isOnMobileDataState = mutableStateOf(false) + // Service Manager is only active when the activity is active. + private val serviceManager = ServiceManager() + @OptIn(ExperimentalMaterial3WindowSizeClassApi::class) @RequiresApi(Build.VERSION_CODES.R) override fun onCreate(savedInstanceState: Bundle?) { @@ -88,7 +91,7 @@ class MainActivity : AppCompatActivity() { accountStateViewModel.tryLoginExistingAccountAsync() } - AccountScreen(accountStateViewModel, sharedPreferencesViewModel) + AccountScreen(accountStateViewModel, sharedPreferencesViewModel, serviceManager) } } } @@ -102,9 +105,9 @@ class MainActivity : AppCompatActivity() { DefaultMutedSetting.value = true // Only starts after login - if (ServiceManager.shouldPauseService) { + if (serviceManager.shouldPauseService) { GlobalScope.launch(Dispatchers.IO) { - ServiceManager.justStart() + serviceManager.justStart() } } @@ -117,7 +120,7 @@ class MainActivity : AppCompatActivity() { override fun onPause() { LanguageTranslatorService.clear() - ServiceManager.cleanObservers() + serviceManager.cleanObservers() // if (BuildConfig.DEBUG) { GlobalScope.launch(Dispatchers.IO) { @@ -125,9 +128,9 @@ class MainActivity : AppCompatActivity() { } // } - if (ServiceManager.shouldPauseService) { + if (serviceManager.shouldPauseService) { GlobalScope.launch(Dispatchers.IO) { - ServiceManager.pauseForGood() + serviceManager.pauseForGood() } } @@ -153,7 +156,7 @@ class MainActivity : AppCompatActivity() { super.onTrimMemory(level) println("Trim Memory $level") GlobalScope.launch(Dispatchers.Default) { - ServiceManager.trimMemory() + serviceManager.trimMemory() } } @@ -163,7 +166,7 @@ class MainActivity : AppCompatActivity() { super.onAvailable(network) GlobalScope.launch(Dispatchers.IO) { - ServiceManager.forceRestartIfItShould() + serviceManager.forceRestartIfItShould() } } @@ -182,7 +185,7 @@ class MainActivity : AppCompatActivity() { if (isOnMobileDataState.value != isOnMobileData) { isOnMobileDataState.value = isOnMobileData - ServiceManager.forceRestartIfItShould() + serviceManager.forceRestartIfItShould() } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountScreen.kt index a819d28ef..3d6c804ee 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountScreen.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -19,6 +20,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.ServiceManager import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.MainScreen @@ -27,44 +29,55 @@ import com.vitorpamplona.amethyst.ui.screen.loggedOff.LoginPage @Composable fun AccountScreen( accountStateViewModel: AccountStateViewModel, - sharedPreferencesViewModel: SharedPreferencesViewModel + sharedPreferencesViewModel: SharedPreferencesViewModel, + serviceManager: ServiceManager ) { val accountState by accountStateViewModel.accountContent.collectAsStateWithLifecycle() - Column() { - Crossfade( - targetState = accountState, - animationSpec = tween(durationMillis = 100), - label = "AccountState" - ) { state -> - when (state) { - is AccountState.Loading -> { - LoadingAccounts() + Crossfade( + targetState = accountState, + animationSpec = tween(durationMillis = 100), + label = "AccountState" + ) { state -> + when (state) { + is AccountState.Loading -> { + LoadingAccounts() + } + is AccountState.LoggedOff -> { + LaunchedEffect(key1 = accountState) { + serviceManager.pauseForGood() } - is AccountState.LoggedOff -> { - LoginPage(accountStateViewModel, isFirstLogin = true) + + LoginPage(accountStateViewModel, isFirstLogin = true) + } + is AccountState.LoggedIn -> { + LaunchedEffect(key1 = accountState) { + serviceManager.restartIfDifferentAccount(state.account) } - is AccountState.LoggedIn -> { - CompositionLocalProvider( - LocalViewModelStoreOwner provides state.currentViewModelStore - ) { - LoggedInPage( - state.account, - accountStateViewModel, - sharedPreferencesViewModel - ) - } + + CompositionLocalProvider( + LocalViewModelStoreOwner provides state.currentViewModelStore + ) { + LoggedInPage( + state.account, + accountStateViewModel, + sharedPreferencesViewModel + ) } - is AccountState.LoggedInViewOnly -> { - CompositionLocalProvider( - LocalViewModelStoreOwner provides state.currentViewModelStore - ) { - LoggedInPage( - state.account, - accountStateViewModel, - sharedPreferencesViewModel - ) - } + } + is AccountState.LoggedInViewOnly -> { + LaunchedEffect(key1 = accountState) { + serviceManager.restartIfDifferentAccount(state.account) + } + + CompositionLocalProvider( + LocalViewModelStoreOwner provides state.currentViewModelStore + ) { + LoggedInPage( + state.account, + accountStateViewModel, + sharedPreferencesViewModel + ) } } } @@ -78,7 +91,7 @@ fun LoggedInPage( sharedPreferencesViewModel: SharedPreferencesViewModel ) { val accountViewModel: AccountViewModel = viewModel( - key = "AccountStateViewModel", + key = "AccountViewModel", factory = AccountViewModel.Factory( account, sharedPreferencesViewModel.sharedPrefs diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt index 0690b4f93..f96cf6c3f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/AccountStateViewModel.kt @@ -6,7 +6,6 @@ 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 @@ -78,16 +77,12 @@ class AccountStateViewModel() : ViewModel() { startUI(account) } - @OptIn(DelicateCoroutinesApi::class) suspend fun startUI(account: Account) = withContext(Dispatchers.Main) { if (account.keyPair.privKey != null) { _accountContent.update { AccountState.LoggedIn(account) } } else { _accountContent.update { AccountState.LoggedInViewOnly(account) } } - GlobalScope.launch(Dispatchers.IO) { - ServiceManager.restartIfDifferentAccount(account) - } account.saveable.observeForever(saveListener) }