Don't keep references to conversations and archivedConversations realmResults in MainViewModel

This commit is contained in:
Moez Bhatti
2018-03-27 18:43:57 -04:00
parent d9a3e17886
commit 2228dc2bc6
7 changed files with 39 additions and 54 deletions
@@ -26,14 +26,14 @@ import javax.inject.Inject
class ConversationItemTouchCallback @Inject constructor() : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
val swipes: Subject<Int> = PublishSubject.create()
val swipes: Subject<Long> = PublishSubject.create()
override fun onMove(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?, target: RecyclerView.ViewHolder?): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
swipes.onNext(viewHolder.adapterPosition)
swipes.onNext(viewHolder.itemId)
}
}
@@ -49,6 +49,11 @@ class ConversationsAdapter @Inject constructor(
val longClicks: Subject<Long> = PublishSubject.create()
private val disposables = CompositeDisposable()
private var attachedRecyclerViews = 0
init {
setHasStableIds(true)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QkViewHolder {
val layoutRes = when (viewType) {
@@ -67,8 +72,16 @@ class ConversationsAdapter @Inject constructor(
return QkViewHolder(view)
}
fun isAttachedToRecyclerView() = attachedRecyclerViews > 0
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
attachedRecyclerViews++
}
override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
super.onDetachedFromRecyclerView(recyclerView)
attachedRecyclerViews--
disposables.clear()
}
@@ -88,6 +101,10 @@ class ConversationsAdapter @Inject constructor(
view.snippet.text = if (message.isMe()) "You: ${message.getSummary()}" else message.getSummary()
}
override fun getItemId(index: Int): Long {
return getItem(index)!!.conversation!!.id
}
override fun getItemViewType(position: Int): Int {
return if (getItem(position)!!.read) 0 else 1
}
@@ -31,6 +31,7 @@ import android.support.v7.widget.helper.ItemTouchHelper
import android.view.Gravity
import android.view.Menu
import android.view.MenuItem
import android.view.View
import com.jakewharton.rxbinding2.support.v4.widget.drawerOpen
import com.jakewharton.rxbinding2.view.clicks
import com.jakewharton.rxbinding2.widget.textChanges
@@ -181,6 +182,12 @@ class MainActivity : QkThemedActivity<MainViewModel>(), MainView {
override fun onItemRangeChanged(positionStart: Int, itemCount: Int) {
onItemRangeInserted(positionStart, itemCount)
}
override fun onChanged() {
if (conversationsAdapter.isAttachedToRecyclerView()) {
empty.setVisible(conversationsAdapter.itemCount == 0, View.INVISIBLE)
}
}
})
}
@@ -203,7 +210,6 @@ class MainActivity : QkThemedActivity<MainViewModel>(), MainView {
itemTouchHelper.attachToRecyclerView(recyclerView)
menuItemAdapter.data = state.page.menu
empty.setText(R.string.inbox_empty_text)
empty.setVisible(state.page.empty && !state.syncing)
compose.setVisible(true)
}
@@ -214,7 +220,6 @@ class MainActivity : QkThemedActivity<MainViewModel>(), MainView {
itemTouchHelper.attachToRecyclerView(null)
menuItemAdapter.data = state.page.menu
empty.setText(R.string.archived_empty_text)
empty.setVisible(state.page.empty && !state.syncing)
compose.setVisible(true)
}
@@ -224,7 +229,6 @@ class MainActivity : QkThemedActivity<MainViewModel>(), MainView {
itemTouchHelper.attachToRecyclerView(null)
menuItemAdapter.data = ArrayList()
empty.setText(R.string.scheduled_empty_text)
empty.setVisible(state.page.empty && !state.syncing)
compose.setVisible(false)
}
}
@@ -33,15 +33,12 @@ sealed class MainPage
data class Inbox(
val showClearButton: Boolean = false,
val data: RealmResults<Message>? = null,
val empty: Boolean = false,
val menu: List<MenuItem> = ArrayList(),
val showArchivedSnackbar: Boolean = false) : MainPage()
data class Archived(
val data: RealmResults<Message>? = null,
val empty: Boolean = false,
val menu: List<MenuItem> = ArrayList()) : MainPage()
data class Scheduled(
val data: Any? = null,
val empty: Boolean = false) : MainPage()
val data: Any? = null) : MainPage()
@@ -18,8 +18,8 @@
*/
package feature.main
import io.reactivex.Observable
import common.base.QkView
import io.reactivex.Observable
interface MainView : QkView<MainState> {
@@ -32,7 +32,7 @@ interface MainView : QkView<MainState> {
val conversationLongClickIntent: Observable<Long>
val conversationMenuItemIntent: Observable<Int>
val confirmDeleteIntent: Observable<Unit>
val swipeConversationIntent: Observable<Int>
val swipeConversationIntent: Observable<Long>
val undoSwipeConversationIntent: Observable<Unit>
fun clearSearch()
@@ -44,9 +44,6 @@ import io.realm.Realm
import model.SyncLog
import repository.MessageRepository
import util.Preferences
import util.extensions.asObservable
import util.extensions.mapNotNull
import util.extensions.toFlowable
import java.util.concurrent.TimeUnit
import javax.inject.Inject
@@ -64,30 +61,6 @@ class MainViewModel : QkViewModel<MainView, MainState>(MainState()) {
@Inject lateinit var partialSync: PartialSync
@Inject lateinit var prefs: Preferences
private val conversations by lazy {
messageRepo.getConversations().also {
it.asFlowable()
.withLatestFrom(state.toFlowable(), { conversations, state ->
(state.page as? Inbox)?.let { page ->
newState { it.copy(page = page.copy(empty = conversations.isEmpty())) }
}
conversations
})
}
}
private val archivedConversations by lazy {
messageRepo.getConversations(true).also {
it.asFlowable()
.withLatestFrom(state.toFlowable(), { conversations, state ->
(state.page as? Archived)?.let { page ->
newState { it.copy(page = page.copy(empty = conversations.isEmpty())) }
}
conversations
})
}
}
private val menuArchive by lazy { MenuItem(context.getString(R.string.menu_archive), 0) }
private val menuUnarchive by lazy { MenuItem(context.getString(R.string.menu_unarchive), 1) }
private val menuDelete by lazy { MenuItem(context.getString(R.string.menu_delete), 2) }
@@ -113,7 +86,7 @@ class MainViewModel : QkViewModel<MainView, MainState>(MainState()) {
.distinctUntilChanged()
.subscribe { syncing -> newState { it.copy(syncing = syncing) } }
newState { it.copy(page = Inbox(data = conversations)) }
newState { it.copy(page = Inbox(data = messageRepo.getConversations())) }
// Migrate the preferences from 2.7.3 if necessary
migratePreferences.execute(Unit)
@@ -141,13 +114,11 @@ class MainViewModel : QkViewModel<MainView, MainState>(MainState()) {
.debounce(200, TimeUnit.MILLISECONDS)
.withLatestFrom(state, { query, state ->
if (state.page is Inbox) {
val conversations = when {
query.isEmpty() -> conversations
else -> conversations.filter { conversationFilter.filter(it, query) }
}
/*val conversations = messageRepo.getConversationsSnapshot()
.filter { conversationFilter.filter(it, query) }
//val page = state.page.copy(showClearButton = query.isNotEmpty(), data = conversations)
//newState { it.copy(page = page) }
val page = state.page.copy(showClearButton = query.isNotEmpty(), data = conversations)
newState { it.copy(page = page) }*/
}
})
.autoDisposable(view.scope())
@@ -173,8 +144,8 @@ class MainViewModel : QkViewModel<MainView, MainState>(MainState()) {
.distinctUntilChanged()
.doOnNext {
when (it) {
DrawerItem.INBOX -> newState { it.copy(page = Inbox(data = conversations)) }
DrawerItem.ARCHIVED -> newState { it.copy(page = Archived(archivedConversations)) }
DrawerItem.INBOX -> newState { it.copy(page = Inbox(data = messageRepo.getConversations())) }
DrawerItem.ARCHIVED -> newState { it.copy(page = Archived(messageRepo.getConversations(true))) }
DrawerItem.SCHEDULED -> newState { it.copy(page = Scheduled()) }
else -> {
} // Do nothing
@@ -235,11 +206,7 @@ class MainViewModel : QkViewModel<MainView, MainState>(MainState()) {
.autoDisposable(view.scope())
.subscribe { threadId -> deleteConversation.execute(threadId) }
val swipedConversation = view.swipeConversationIntent
.withLatestFrom(conversations.asObservable(), { position, conversations -> conversations[position] })
.mapNotNull { message -> message?.conversation?.id }
swipedConversation
view.swipeConversationIntent
.withLatestFrom(state, { threadId, state ->
markArchived.execute(threadId) {
if (state.page is Inbox) {
@@ -261,7 +228,7 @@ class MainViewModel : QkViewModel<MainView, MainState>(MainState()) {
.subscribe()
view.undoSwipeConversationIntent
.withLatestFrom(swipedConversation, { _, threadId -> threadId })
.withLatestFrom(view.swipeConversationIntent, { _, threadId -> threadId })
.autoDisposable(view.scope())
.subscribe { threadId -> markUnarchived.execute(threadId) }
}