Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix show only personal setting not updating the view immediately #1238

Original file line number Diff line number Diff line change
Expand Up @@ -286,15 +286,15 @@ class AccountSettings @AssistedInject constructor(

// UI settings

data class ShowOnlyPersonal(
val onlyPersonal: Boolean,
val locked: Boolean
)

fun getShowOnlyPersonal(): ShowOnlyPersonal {
fun getShowOnlyPersonal(): Boolean {
@Suppress("DEPRECATION")
val pair = getShowOnlyPersonalPair()
return pair.first
}
fun getShowOnlyPersonalLocked(): Boolean {
@Suppress("DEPRECATION")
val pair = getShowOnlyPersonalPair()
return ShowOnlyPersonal(onlyPersonal = pair.first, locked = !pair.second)
return !pair.second
}

/**
Expand Down
24 changes: 13 additions & 11 deletions app/src/main/kotlin/at/bitfire/davdroid/ui/account/AccountScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ import androidx.paging.compose.LazyPagingItems
import androidx.paging.compose.collectAsLazyPagingItems
import at.bitfire.davdroid.R
import at.bitfire.davdroid.db.Collection
import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.ui.AppTheme
import at.bitfire.davdroid.ui.PermissionsActivity
import at.bitfire.davdroid.ui.account.AccountProgress
Expand Down Expand Up @@ -114,9 +113,8 @@ fun AccountScreen(
error = model.error,
onResetError = model::resetError,
invalidAccount = model.invalidAccount.collectAsStateWithLifecycle(false).value,
showOnlyPersonal = model.showOnlyPersonal.collectAsStateWithLifecycle(
initialValue = AccountSettings.ShowOnlyPersonal(onlyPersonal = false, locked = false)
).value,
showOnlyPersonal = model.showOnlyPersonal.collectAsStateWithLifecycle().value,
showOnlyPersonalLocked = model.showOnlyPersonalLocked.collectAsStateWithLifecycle().value,
onSetShowOnlyPersonal = model::setShowOnlyPersonal,
hasCardDav = cardDavService != null,
canCreateAddressBook = model.canCreateAddressBook.collectAsStateWithLifecycle(false).value,
Expand Down Expand Up @@ -169,7 +167,8 @@ fun AccountScreen(
error: String? = null,
onResetError: () -> Unit = {},
invalidAccount: Boolean = false,
showOnlyPersonal: AccountSettings.ShowOnlyPersonal,
showOnlyPersonal: Boolean = false,
showOnlyPersonalLocked: Boolean = false,
onSetShowOnlyPersonal: (showOnlyPersonal: Boolean) -> Unit = {},
hasCardDav: Boolean,
canCreateAddressBook: Boolean,
Expand Down Expand Up @@ -257,6 +256,7 @@ fun AccountScreen(
canCreateCalendar = canCreateCalendar,
onCreateCalendar = onCreateCalendar,
showOnlyPersonal = showOnlyPersonal,
showOnlyPersonalLocked = showOnlyPersonalLocked,
onSetShowOnlyPersonal = onSetShowOnlyPersonal,
currentPage = pagerState.currentPage,
idxCardDav = idxCardDav,
Expand Down Expand Up @@ -440,7 +440,8 @@ fun AccountScreen_Actions(
onCreateAddressBook: () -> Unit,
canCreateCalendar: Boolean,
onCreateCalendar: () -> Unit,
showOnlyPersonal: AccountSettings.ShowOnlyPersonal,
showOnlyPersonal: Boolean,
showOnlyPersonalLocked: Boolean,
onSetShowOnlyPersonal: (showOnlyPersonal: Boolean) -> Unit,
currentPage: Int,
idxCardDav: Int?,
Expand Down Expand Up @@ -513,8 +514,8 @@ fun AccountScreen_Actions(
LocalMinimumInteractiveComponentSize provides Dp.Unspecified
) {
Checkbox(
checked = showOnlyPersonal.onlyPersonal,
enabled = !showOnlyPersonal.locked,
checked = showOnlyPersonal,
enabled = !showOnlyPersonalLocked,
onCheckedChange = {
onSetShowOnlyPersonal(it)
overflowOpen = false
Expand All @@ -527,10 +528,10 @@ fun AccountScreen_Actions(
Text(stringResource(R.string.account_only_personal))
},
onClick = {
onSetShowOnlyPersonal(!showOnlyPersonal.onlyPersonal)
onSetShowOnlyPersonal(!showOnlyPersonal)
overflowOpen = false
},
enabled = !showOnlyPersonal.locked
enabled = !showOnlyPersonalLocked
)

// rename account
Expand Down Expand Up @@ -651,7 +652,8 @@ fun AccountScreen_ServiceTab(
fun AccountScreen_Preview() {
AccountScreen(
accountName = "test@example.com",
showOnlyPersonal = AccountSettings.ShowOnlyPersonal(onlyPersonal = false, locked = true),
showOnlyPersonal = false,
showOnlyPersonalLocked = true,
hasCardDav = true,
canCreateAddressBook = false,
cardDavProgress = AccountProgress.Active,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ import android.content.Context
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.asFlow
import androidx.lifecycle.switchMap
import androidx.lifecycle.viewModelScope
import at.bitfire.davdroid.R
import at.bitfire.davdroid.db.Collection
Expand All @@ -34,10 +30,13 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.logging.Level
import java.util.logging.Logger

Expand All @@ -62,26 +61,32 @@ class AccountScreenModel @AssistedInject constructor(
fun create(account: Account): AccountScreenModel
}

private val _showOnlyPersonal = MutableStateFlow(false)
val showOnlyPersonal = _showOnlyPersonal.asStateFlow()

private var _showOnlyPersonalLocked = MutableStateFlow(false)
val showOnlyPersonalLocked = _showOnlyPersonalLocked.asStateFlow()

/**
* Only acquire account settings on a worker thread!
*/
private val accountSettings by lazy { accountSettingsFactory.create(account) }

private suspend fun reload() = withContext(Dispatchers.Default) {
_showOnlyPersonal.value = accountSettings.getShowOnlyPersonal()
_showOnlyPersonalLocked.value = accountSettings.getShowOnlyPersonalLocked()
}

/** whether the account is invalid and the screen shall be closed */
val invalidAccount = accountRepository.getAllFlow().map { accounts ->
!accounts.contains(account)
}

private val refreshSettingsSignal = MutableLiveData(Unit)
val showOnlyPersonal = refreshSettingsSignal.switchMap<Unit, AccountSettings.ShowOnlyPersonal> {
object : LiveData<AccountSettings.ShowOnlyPersonal>() {
init {
viewModelScope.launch(Dispatchers.IO) {
val settings = accountSettingsFactory.create(account)
postValue(settings.getShowOnlyPersonal())
}
}
fun setShowOnlyPersonal(showOnlyPersonal: Boolean) {
CoroutineScope(Dispatchers.Default).launch {
accountSettings.setShowOnlyPersonal(showOnlyPersonal)
reload()
}
}.asFlow()
fun setShowOnlyPersonal(showOnlyPersonal: Boolean) = viewModelScope.launch(Dispatchers.IO) {
val settings = accountSettingsFactory.create(account)
settings.setShowOnlyPersonal(showOnlyPersonal)
refreshSettingsSignal.postValue(Unit)
}

val cardDavSvc = serviceRepository
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ import androidx.paging.map
import at.bitfire.davdroid.db.Collection
import at.bitfire.davdroid.db.Service
import at.bitfire.davdroid.repository.DavCollectionRepository
import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.settings.Settings
import at.bitfire.davdroid.settings.SettingsManager
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flattenConcat
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import javax.inject.Inject
Expand All @@ -43,7 +42,7 @@ class GetServiceCollectionPagerUseCase @Inject constructor(
operator fun invoke(
serviceFlow: Flow<Service?>,
collectionType: String,
showOnlyPersonalFlow: Flow<AccountSettings.ShowOnlyPersonal?>
showOnlyPersonalFlow: Flow<Boolean>
): Flow<PagingData<Collection>> =
combine(serviceFlow, showOnlyPersonalFlow, forceReadOnlyAddressBooksFlow) { service, onlyPersonal, forceReadOnlyAddressBooks ->
if (service == null)
Expand All @@ -52,7 +51,7 @@ class GetServiceCollectionPagerUseCase @Inject constructor(
val dataFlow = Pager(
config = PagingConfig(PAGER_SIZE),
pagingSourceFactory = {
if (onlyPersonal?.onlyPersonal == true)
if (onlyPersonal == true)
collectionRepository.pagePersonalByServiceAndType(service.id, collectionType)
else
collectionRepository.pageByServiceAndType(service.id, collectionType)
Expand All @@ -72,6 +71,6 @@ class GetServiceCollectionPagerUseCase @Inject constructor(
else
dataFlow
}
}.flattenConcat()
}.flatMapLatest { it }

}
Loading