Better refreshing state handling for AccountViewModel (#4680)

Closes #4353 by addressing the last edge case: The swipe to refresh
won't be enabled before something is loaded, preventing multiple loads
at the same time. After the first load, the swipe to refresh itself
prevents multiple loads: It can be swiped only once.

---------

Co-authored-by: Goooler <wangzongler@gmail.com>
This commit is contained in:
Konrad Pozniak 2024-09-15 17:32:19 +02:00 committed by GitHub
parent 92adc0fad5
commit f2a2c16464
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 16 additions and 18 deletions

View File

@ -387,7 +387,10 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvide
viewModel.accountData.collect {
if (it == null) return@collect
when (it) {
is Success -> onAccountChanged(it.data)
is Success -> {
onAccountChanged(it.data)
binding.swipeToRefreshLayout.isEnabled = true
}
is Error -> {
Snackbar.make(
binding.accountCoordinatorLayout,
@ -396,6 +399,7 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvide
)
.setAction(R.string.action_retry) { viewModel.refresh() }
.show()
binding.swipeToRefreshLayout.isEnabled = true
}
is Loading -> { }
}
@ -438,10 +442,11 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvide
* Setup swipe to refresh layout
*/
private fun setupRefreshLayout() {
binding.swipeToRefreshLayout.isEnabled = false // will only be enabled after the first load completed
binding.swipeToRefreshLayout.setOnRefreshListener { onRefresh() }
lifecycleScope.launch {
viewModel.isRefreshing.collect { isRefreshing ->
binding.swipeToRefreshLayout.isRefreshing = isRefreshing == true
viewModel.isRefreshing.collect {
binding.swipeToRefreshLayout.isRefreshing = it
}
}
}
@ -1030,7 +1035,6 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvide
return true
}
R.id.action_refresh -> {
binding.swipeToRefreshLayout.isRefreshing = true
onRefresh()
return true
}

View File

@ -22,13 +22,9 @@ import com.keylesspalace.tusky.util.getDomain
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
@ -48,10 +44,8 @@ class AccountViewModel @Inject constructor(
private val _noteSaved = MutableStateFlow(false)
val noteSaved: StateFlow<Boolean> = _noteSaved.asStateFlow()
private val _isRefreshing = MutableSharedFlow<Boolean>(1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
val isRefreshing: SharedFlow<Boolean> = _isRefreshing.asSharedFlow()
private var isDataLoading = false
private val _isRefreshing = MutableStateFlow(false)
val isRefreshing: StateFlow<Boolean> = _isRefreshing.asStateFlow()
lateinit var accountId: String
var isSelf = false
@ -78,7 +72,9 @@ class AccountViewModel @Inject constructor(
private fun obtainAccount(reload: Boolean = false) {
if (_accountData.value == null || reload) {
isDataLoading = true
if (reload) {
_isRefreshing.value = true
}
_accountData.value = Loading()
viewModelScope.launch {
@ -89,14 +85,12 @@ class AccountViewModel @Inject constructor(
isFromOwnDomain = domain == activeAccount.domain
_accountData.value = Success(account)
isDataLoading = false
_isRefreshing.emit(false)
_isRefreshing.value = false
},
{ t ->
Log.w(TAG, "failed obtaining account", t)
_accountData.value = Error(cause = t)
isDataLoading = false
_isRefreshing.emit(false)
_isRefreshing.value = false
}
)
}
@ -318,7 +312,7 @@ class AccountViewModel @Inject constructor(
}
private fun reload(isReload: Boolean = false) {
if (isDataLoading) {
if (_isRefreshing.value) {
return
}
accountId.let {