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