Move unapprovedMessageCount to IO

pull/1502/head
Andrew 1 month ago
parent b757691334
commit cd302f9f27

@ -185,7 +185,6 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
binding.seedReminderView.isVisible = false
}
}
setupMessageRequestsBanner()
// Set up recycler view
binding.globalSearchInputLayout.listener = this
homeAdapter.setHasStableIds(true)
@ -218,9 +217,9 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
// Subscribe to threads and update the UI
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
homeViewModel.threads
homeViewModel.data
.filterNotNull() // We don't actually want the null value here as it indicates a loading state (maybe we need a loading state?)
.collectLatest { threads ->
.collectLatest { data ->
val manager = binding.recyclerView.layoutManager as LinearLayoutManager
val firstPos = manager.findFirstCompletelyVisibleItemPosition()
val offsetTop = if(firstPos >= 0) {
@ -228,9 +227,9 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
manager.getDecoratedTop(view) - manager.getTopDecorationHeight(view)
} ?: 0
} else 0
homeAdapter.data = threads
homeAdapter.data = data
if(firstPos >= 0) { manager.scrollToPositionWithOffset(firstPos, offsetTop) }
setupMessageRequestsBanner()
setupMessageRequestsBanner(data.unapprovedConversationCount, data.hasHiddenMessageRequests)
updateEmptyState()
}
}
@ -341,10 +340,9 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
binding.newConversationButton.isVisible = !isShown
}
private fun setupMessageRequestsBanner() {
val messageRequestCount = threadDb.unapprovedConversationCount
private fun setupMessageRequestsBanner(messageRequestCount: Int, hasHiddenMessageRequests: Boolean) {
// Set up message requests
if (messageRequestCount > 0 && !textSecurePreferences.hasHiddenMessageRequests()) {
if (messageRequestCount > 0 && !hasHiddenMessageRequests) {
with(ViewMessageRequestBannerBinding.inflate(layoutInflater)) {
unreadCountTextView.text = messageRequestCount.toString()
timestampTextView.text = DateUtils.getDisplayFormattedTimeSpanString(
@ -664,7 +662,6 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
text("Hide message requests?")
button(R.string.yes) {
textSecurePreferences.setHasHiddenMessageRequests()
setupMessageRequestsBanner()
homeViewModel.tryReload()
}
button(R.string.no)

@ -25,11 +25,9 @@ class HomeAdapter(
var header: View? = null
var data: HomeViewModel.Data = HomeViewModel.Data(emptyList(), emptySet())
var data: HomeViewModel.Data = HomeViewModel.Data(emptyList(), 0, false, emptySet())
set(newData) {
if (field === newData) {
return
}
if (field === newData) return
val diff = HomeDiffUtil(field, newData, context, configFactory)
val diffResult = DiffUtil.calculateDiff(diff)

@ -15,11 +15,14 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.withContext
import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.database.DatabaseContentProviders
import org.thoughtcrime.securesms.database.ThreadDatabase
@ -30,9 +33,10 @@ import dagger.hilt.android.qualifiers.ApplicationContext as ApplicationContextQu
@HiltViewModel
class HomeViewModel @Inject constructor(
private val threadDb: ThreadDatabase,
private val contentResolver: ContentResolver,
@ApplicationContextQualifier private val context: Context,
private val threadDb: ThreadDatabase,
private val contentResolver: ContentResolver,
private val prefs: TextSecurePreferences,
@ApplicationContextQualifier private val context: Context,
) : ViewModel() {
// SharedFlow that emits whenever the user asks us to reload the conversation
private val manualReloadTrigger = MutableSharedFlow<Unit>(
@ -46,8 +50,18 @@ class HomeViewModel @Inject constructor(
* This flow will emit whenever the user asks us to reload the conversation list or
* whenever the conversation list changes.
*/
val threads: StateFlow<Data?> = combine(observeConversationList(), observeTypingStatus(), ::Data)
.stateIn(viewModelScope, SharingStarted.Eagerly, null)
val data: StateFlow<Data?> = combine(
observeConversationList(),
unapprovedConversationCount(),
hasHiddenMessageRequestsFlow(),
observeTypingStatus(),
::Data
).stateIn(viewModelScope, SharingStarted.Eagerly, null)
private fun hasHiddenMessageRequestsFlow() = TextSecurePreferences.events
.filter { it == TextSecurePreferences.HAS_HIDDEN_MESSAGE_REQUESTS }
.map { prefs.hasHiddenMessageRequests() }
.onStart { emit(prefs.hasHiddenMessageRequests()) }
private fun observeTypingStatus(): Flow<Set<Long>> =
ApplicationContext.getInstance(context).typingStatusRepository
@ -56,30 +70,38 @@ class HomeViewModel @Inject constructor(
.onStart { emit(emptySet()) }
.distinctUntilChanged()
private fun unapprovedConversationCount() =
contentResolver.observeChanges(DatabaseContentProviders.ConversationList.CONTENT_URI)
.flowOn(Dispatchers.IO)
.map { threadDb.unapprovedConversationCount }
.onStart { emit(threadDb.unapprovedConversationCount) }
@Suppress("OPT_IN_USAGE")
private fun observeConversationList(): Flow<List<ThreadRecord>> = merge(
manualReloadTrigger,
contentResolver.observeChanges(DatabaseContentProviders.ConversationList.CONTENT_URI))
.debounce(CHANGE_NOTIFICATION_DEBOUNCE_MILLS)
.onStart { emit(Unit) }
.mapLatest { _ ->
withContext(Dispatchers.IO) {
threadDb.approvedConversationList.use { openCursor ->
val reader = threadDb.readerFor(openCursor)
buildList(reader.count) {
while (true) {
add(reader.next ?: break)
}
}
manualReloadTrigger,
contentResolver.observeChanges(DatabaseContentProviders.ConversationList.CONTENT_URI)
)
.flowOn(Dispatchers.IO)
.debounce(CHANGE_NOTIFICATION_DEBOUNCE_MILLS)
.onStart { emit(Unit) }
.mapLatest { _ ->
threadDb.approvedConversationList.use { openCursor ->
val reader = threadDb.readerFor(openCursor)
buildList(reader.count) {
while (true) {
add(reader.next ?: break)
}
}
}
}
fun tryReload() = manualReloadTrigger.tryEmit(Unit)
data class Data(
val threads: List<ThreadRecord>,
val typingThreadIDs: Set<Long>
val threads: List<ThreadRecord>,
val unapprovedConversationCount: Int,
val hasHiddenMessageRequests: Boolean,
val typingThreadIDs: Set<Long>
)
companion object {

Loading…
Cancel
Save