mirror of
https://github.com/oxen-io/session-android.git
synced 2025-01-11 16:33:39 +00:00
OOM feedback
This commit is contained in:
parent
31f4de22cd
commit
c0128b88de
@ -881,7 +881,7 @@ public class ThreadDatabase extends Database {
|
||||
this.cursor = cursor;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
public int getCount() {
|
||||
return cursor == null ? 0 : cursor.getCount();
|
||||
}
|
||||
|
||||
|
@ -25,14 +25,16 @@ class HomeAdapter(
|
||||
|
||||
var header: View? = null
|
||||
|
||||
var data: HomeViewModel.HomeData = HomeViewModel.HomeData(emptyList(), emptySet())
|
||||
var data: HomeViewModel.Data = HomeViewModel.Data(emptyList(), emptySet())
|
||||
set(newData) {
|
||||
if (field !== newData) {
|
||||
val diff = HomeDiffUtil(field, newData, context, configFactory)
|
||||
val diffResult = DiffUtil.calculateDiff(diff)
|
||||
field = newData
|
||||
diffResult.dispatchUpdatesTo(this as ListUpdateCallback)
|
||||
if (field === newData) {
|
||||
return
|
||||
}
|
||||
|
||||
val diff = HomeDiffUtil(field, newData, context, configFactory)
|
||||
val diffResult = DiffUtil.calculateDiff(diff)
|
||||
field = newData
|
||||
diffResult.dispatchUpdatesTo(this as ListUpdateCallback)
|
||||
}
|
||||
|
||||
fun hasHeaderView(): Boolean = header != null
|
||||
|
@ -2,15 +2,14 @@ package org.thoughtcrime.securesms.home
|
||||
|
||||
import android.content.Context
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||
import org.thoughtcrime.securesms.dependencies.ConfigFactory
|
||||
import org.thoughtcrime.securesms.util.getConversationUnread
|
||||
|
||||
class HomeDiffUtil(
|
||||
private val old: HomeViewModel.HomeData,
|
||||
private val new: HomeViewModel.HomeData,
|
||||
private val context: Context,
|
||||
private val configFactory: ConfigFactory
|
||||
private val old: HomeViewModel.Data,
|
||||
private val new: HomeViewModel.Data,
|
||||
private val context: Context,
|
||||
private val configFactory: ConfigFactory
|
||||
): DiffUtil.Callback() {
|
||||
|
||||
override fun getOldListSize(): Int = old.threads.size
|
||||
|
@ -8,6 +8,7 @@ import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
@ -30,8 +31,8 @@ import dagger.hilt.android.qualifiers.ApplicationContext as ApplicationContextQu
|
||||
@HiltViewModel
|
||||
class HomeViewModel @Inject constructor(
|
||||
private val threadDb: ThreadDatabase,
|
||||
contentResolver: ContentResolver,
|
||||
@ApplicationContextQualifier context: Context,
|
||||
private val contentResolver: ContentResolver,
|
||||
@ApplicationContextQualifier private val context: Context,
|
||||
) : ViewModel() {
|
||||
// SharedFlow that emits whenever the user asks us to reload the conversation
|
||||
private val manualReloadTrigger = MutableSharedFlow<Unit>(
|
||||
@ -45,45 +46,40 @@ class HomeViewModel @Inject constructor(
|
||||
* This flow will emit whenever the user asks us to reload the conversation list or
|
||||
* whenever the conversation list changes.
|
||||
*/
|
||||
@Suppress("OPT_IN_USAGE")
|
||||
val threads: StateFlow<HomeData?> =
|
||||
combine(
|
||||
// The conversation list data
|
||||
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.length) {
|
||||
while (true) {
|
||||
add(reader.next ?: break)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// The typing status of each thread
|
||||
ApplicationContext.getInstance(context).typingStatusRepository
|
||||
.typingThreads
|
||||
.asFlow()
|
||||
.onStart { emit(emptySet()) }
|
||||
.distinctUntilChanged(),
|
||||
|
||||
// The final result that we emit to the UI
|
||||
::HomeData
|
||||
)
|
||||
val threads: StateFlow<Data?> = combine(observeConversationList(), observeTypingStatus(), ::Data)
|
||||
.stateIn(viewModelScope, SharingStarted.Eagerly, null)
|
||||
|
||||
private fun observeTypingStatus(): Flow<Set<Long>> =
|
||||
ApplicationContext.getInstance(context).typingStatusRepository
|
||||
.typingThreads
|
||||
.asFlow()
|
||||
.onStart { emit(emptySet()) }
|
||||
.distinctUntilChanged()
|
||||
|
||||
@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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun tryReload() = manualReloadTrigger.tryEmit(Unit)
|
||||
|
||||
data class HomeData(
|
||||
val threads: List<ThreadRecord>,
|
||||
val typingThreadIDs: Set<Long>
|
||||
data class Data(
|
||||
val threads: List<ThreadRecord>,
|
||||
val typingThreadIDs: Set<Long>
|
||||
)
|
||||
|
||||
companion object {
|
||||
|
@ -11,7 +11,7 @@ import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
|
||||
/**
|
||||
* Observe changes to a content URI. This function will emit the URI whenever the content or
|
||||
* Observe changes to a content Uri. This function will emit the Uri whenever the content or
|
||||
* its descendants change, according to the parameter [notifyForDescendants].
|
||||
*/
|
||||
@CheckResult
|
||||
|
Loading…
x
Reference in New Issue
Block a user