Conversation as field in Message

This commit is contained in:
Moez Bhatti
2018-03-27 17:19:07 -04:00
parent dd8fd3216d
commit 9c7ff3e6ea
16 changed files with 110 additions and 130 deletions
@@ -138,8 +138,8 @@ class NotificationManagerImpl @Inject constructor(
return
}
val threadId = message.threadId
val conversation = messageRepo.getConversation(threadId) ?: return
val conversation = message.conversation ?: return
val threadId = conversation.id
val contentIntent = Intent(context, ComposeActivity::class.java).putExtra("threadId", threadId)
val taskStackBuilder = TaskStackBuilder.create(context)
@@ -18,13 +18,13 @@
*/
package common.util.filter
import model.Conversation
import model.Message
import javax.inject.Inject
class ConversationFilter @Inject constructor(private val recipientFilter: RecipientFilter) : Filter<Conversation>() {
class ConversationFilter @Inject constructor(private val recipientFilter: RecipientFilter) : Filter<Message>() {
override fun filter(item: Conversation, query: CharSequence): Boolean {
return item.recipients.any { recipient -> recipientFilter.filter(recipient, query) }
override fun filter(item: Message, query: CharSequence): Boolean {
return item.conversation?.recipients?.any { recipient -> recipientFilter.filter(recipient, query) } ?: false
}
}
@@ -25,20 +25,19 @@ import android.view.ViewGroup
import com.jakewharton.rxbinding2.view.clicks
import com.jakewharton.rxbinding2.view.longClicks
import com.moez.QKSMS.R
import common.Navigator
import common.base.QkViewHolder
import common.util.Colors
import common.util.DateFormatter
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import io.reactivex.subjects.PublishSubject
import io.reactivex.subjects.Subject
import io.realm.RealmRecyclerViewAdapter
import kotlinx.android.synthetic.main.conversation_list_item.view.*
import model.Contact
import model.Conversation
import model.Message
import model.PhoneNumber
import common.Navigator
import common.base.FlowableAdapter
import common.base.QkViewHolder
import repository.MessageRepository
import javax.inject.Inject
@@ -48,7 +47,7 @@ class ConversationsAdapter @Inject constructor(
val messageRepo: MessageRepository,
val dateFormatter: DateFormatter,
val colors: Colors
) : FlowableAdapter<Pair<Conversation, Message>>() {
) : RealmRecyclerViewAdapter<Message, QkViewHolder>(null, true) {
val clicks: Subject<Long> = PublishSubject.create()
val longClicks: Subject<Long> = PublishSubject.create()
@@ -78,8 +77,8 @@ class ConversationsAdapter @Inject constructor(
}
override fun onBindViewHolder(viewHolder: QkViewHolder, position: Int) {
val conversation = getItem(position).first
val message = getItem(position).second
val message = getItem(position)!!
val conversation = message.conversation!!
val view = viewHolder.itemView
view.clicks().subscribe { clicks.onNext(conversation.id) }
@@ -94,16 +93,6 @@ class ConversationsAdapter @Inject constructor(
}
override fun getItemViewType(position: Int): Int {
return if (getItem(position).second.read) 0 else 1
}
override fun areItemsTheSame(old: Pair<Conversation, Message>, new: Pair<Conversation, Message>): Boolean {
return old.first.id == new.first.id
}
override fun areContentsTheSame(old: Pair<Conversation, Message>, new: Pair<Conversation, Message>): Boolean {
return old.second.id == new.second.id &&
old.second.read == new.second.read &&
old.first.recipients == new.first.recipients
return if (getItem(position)!!.read) 0 else 1
}
}
@@ -23,13 +23,13 @@ import android.content.Intent
import com.moez.QKSMS.R
import com.uber.autodispose.android.lifecycle.scope
import com.uber.autodispose.kotlin.autoDisposable
import injection.appComponent
import common.base.QkViewModel
import common.util.extensions.makeToast
import injection.appComponent
import interactor.SaveImage
import io.reactivex.Flowable
import io.reactivex.rxkotlin.plusAssign
import io.reactivex.rxkotlin.withLatestFrom
import common.base.QkViewModel
import repository.MessageRepository
import util.extensions.mapNotNull
import javax.inject.Inject
@@ -54,7 +54,7 @@ class GalleryViewModel(intent: Intent) : QkViewModel<GalleryView, GalleryState>(
disposables += partIdFlowable
.mapNotNull { partId -> messageRepo.getMessageForPart(partId) }
.mapNotNull { message -> messageRepo.getConversation(message.threadId) }
.mapNotNull { message -> message.conversation }
.subscribe { conversation -> newState { it.copy(title = conversation.getTitle()) } }
}
@@ -199,7 +199,7 @@ class MainActivity : QkThemedActivity<MainViewModel>(), MainView {
is Inbox -> {
if (!inbox.isSelected) toolbarSearch.text = null
if (recyclerView.adapter !== conversationsAdapter) recyclerView.adapter = conversationsAdapter
conversationsAdapter.flowable = state.page.data
conversationsAdapter.updateData(state.page.data)
itemTouchHelper.attachToRecyclerView(recyclerView)
menuItemAdapter.data = state.page.menu
empty.setText(R.string.inbox_empty_text)
@@ -210,7 +210,7 @@ class MainActivity : QkThemedActivity<MainViewModel>(), MainView {
is Archived -> {
if (!archived.isSelected) toolbarSearch.setText(R.string.title_archived)
if (recyclerView.adapter !== conversationsAdapter) recyclerView.adapter = conversationsAdapter
conversationsAdapter.flowable = state.page.data
conversationsAdapter.updateData(state.page.data)
itemTouchHelper.attachToRecyclerView(null)
menuItemAdapter.data = state.page.menu
empty.setText(R.string.archived_empty_text)
@@ -18,10 +18,9 @@
*/
package feature.main
import io.reactivex.Flowable
import model.Conversation
import model.Message
import common.MenuItem
import io.realm.RealmResults
import model.Message
data class MainState(
val page: MainPage = Inbox(),
@@ -33,13 +32,13 @@ sealed class MainPage
data class Inbox(
val showClearButton: Boolean = false,
val data: Flowable<List<Pair<Conversation, Message>>>? = null,
val data: RealmResults<Message>? = null,
val empty: Boolean = false,
val menu: List<MenuItem> = ArrayList(),
val showArchivedSnackbar: Boolean = false) : MainPage()
data class Archived(
val data: Flowable<List<Pair<Conversation, Message>>>?,
val data: RealmResults<Message>? = null,
val empty: Boolean = false,
val menu: List<MenuItem> = ArrayList()) : MainPage()
@@ -26,8 +26,11 @@ import android.support.v4.content.ContextCompat
import com.moez.QKSMS.R
import com.uber.autodispose.android.lifecycle.scope
import com.uber.autodispose.kotlin.autoDisposable
import injection.appComponent
import common.MenuItem
import common.Navigator
import common.base.QkViewModel
import common.util.filter.ConversationFilter
import injection.appComponent
import interactor.DeleteConversation
import interactor.MarkAllSeen
import interactor.MarkArchived
@@ -39,11 +42,10 @@ import io.reactivex.rxkotlin.plusAssign
import io.reactivex.rxkotlin.withLatestFrom
import io.realm.Realm
import model.SyncLog
import common.MenuItem
import common.Navigator
import common.base.QkViewModel
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
@@ -63,23 +65,27 @@ class MainViewModel : QkViewModel<MainView, MainState>(MainState()) {
@Inject lateinit var prefs: Preferences
private val conversations by lazy {
messageRepo.getConversations()
.withLatestFrom(state.toFlowable(), { conversations, state ->
(state.page as? Inbox)?.let { page ->
newState { it.copy(page = page.copy(empty = conversations.isEmpty())) }
}
conversations
})
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)
.withLatestFrom(state.toFlowable(), { conversations, state ->
(state.page as? Archived)?.let { page ->
newState { it.copy(page = page.copy(empty = conversations.isEmpty())) }
}
conversations
})
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) }
@@ -137,11 +143,11 @@ class MainViewModel : QkViewModel<MainView, MainState>(MainState()) {
if (state.page is Inbox) {
val conversations = when {
query.isEmpty() -> conversations
else -> conversations.map { list -> list.filter { conversationFilter.filter(it.first, query) } }
else -> conversations.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())
@@ -230,9 +236,8 @@ class MainViewModel : QkViewModel<MainView, MainState>(MainState()) {
.subscribe { threadId -> deleteConversation.execute(threadId) }
val swipedConversation = view.swipeConversationIntent
.withLatestFrom(conversations.toObservable(), { position, conversations -> conversations[position] })
.map { pair -> pair.first }
.map { conversation -> conversation.id }
.withLatestFrom(conversations.asObservable(), { position, conversations -> conversations[position] })
.mapNotNull { message -> message?.conversation?.id }
swipedConversation
.withLatestFrom(state, { threadId, state ->
@@ -38,7 +38,6 @@ import common.util.extensions.dpToPx
import feature.main.MainActivity
import injection.appComponent
import model.Contact
import model.Conversation
import model.Message
import model.PhoneNumber
import repository.MessageRepository
@@ -57,7 +56,7 @@ class WidgetAdapter(intent: Intent) : RemoteViewsService.RemoteViewsFactory {
private val appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID)
private val smallWidget = intent.getBooleanExtra("small_widget", false)
private var conversations: List<Pair<Conversation, Message>> = listOf()
private var conversations: List<Message> = listOf()
private val appWidgetManager by lazy { AppWidgetManager.getInstance(context) }
// Cache colors, load lazily. This entire class is recreated when the widget is recreated,
@@ -98,8 +97,8 @@ class WidgetAdapter(intent: Intent) : RemoteViewsService.RemoteViewsFactory {
}
private fun getConversationView(position: Int): RemoteViews {
val conversation = conversations[position].first
val message = conversations[position].second
val message = conversations[position]
val conversation = message.conversation!!
val remoteViews = RemoteViews(context.packageName, R.layout.widget_list_item)