Loading presentation/src/main/java/com/moez/QKSMS/common/base/QkRealmAdapter.kt +1 −1 Original line number Diff line number Diff line Loading @@ -48,7 +48,7 @@ abstract class QkRealmAdapter<T : RealmModel> : RealmRecyclerViewAdapter<T, QkVi emptyView?.setVisible(data.isLoaded && data.isEmpty()) } val selectionChanges: Subject<List<Long>> = BehaviorSubject.create() val selectionChanges: Subject<List<Long>> = BehaviorSubject.createDefault(listOf()) private var selection = listOf<Long>() Loading presentation/src/main/java/com/moez/QKSMS/feature/blocking/messages/BlockedMessagesAdapter.kt +12 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,16 @@ class BlockedMessagesAdapter @Inject constructor() : QkRealmAdapter<Conversation return QkViewHolder(view).apply { view.setOnClickListener { val conversation = getItem(adapterPosition) ?: return@setOnClickListener clicks.onNext(conversation.id) when (toggleSelection(conversation.id, false)) { true -> view.isActivated = isSelected(conversation.id) false -> clicks.onNext(conversation.id) } } view.setOnLongClickListener { val conversation = getItem(adapterPosition) ?: return@setOnLongClickListener true toggleSelection(conversation.id) view.isActivated = isSelected(conversation.id) true } } } Loading @@ -46,6 +55,8 @@ class BlockedMessagesAdapter @Inject constructor() : QkRealmAdapter<Conversation val conversation = getItem(position) ?: return val view = holder.containerView view.isActivated = isSelected(conversation.id) view.avatars.contacts = conversation.recipients view.title.collapseEnabled = conversation.recipients.size > 1 view.title.text = conversation.getTitle() Loading presentation/src/main/java/com/moez/QKSMS/feature/blocking/messages/BlockedMessagesController.kt +61 −1 Original line number Diff line number Diff line Loading @@ -18,21 +18,37 @@ */ package com.moez.QKSMS.feature.blocking.messages import android.app.AlertDialog import android.content.Context import android.view.Menu import android.view.MenuInflater import android.view.MenuItem import android.view.View import com.moez.QKSMS.R import com.moez.QKSMS.common.base.QkController import com.moez.QKSMS.common.util.Colors import com.moez.QKSMS.feature.blocking.BlockingDialog import com.moez.QKSMS.injection.appComponent import io.reactivex.subjects.PublishSubject import io.reactivex.subjects.Subject import kotlinx.android.synthetic.main.blocked_messages_controller.* import kotlinx.android.synthetic.main.container_activity.* import javax.inject.Inject class BlockedMessagesController : QkController<BlockedMessagesView, BlockedMessagesState, BlockedMessagesPresenter>(), BlockedMessagesView { override val menuReadyIntent: Subject<Unit> = PublishSubject.create() override val optionsItemIntent: Subject<Int> = PublishSubject.create() override val conversationClicks by lazy { blockedMessagesAdapter.clicks } override val selectionChanges by lazy { blockedMessagesAdapter.selectionChanges } override val confirmDeleteIntent: Subject<List<Long>> = PublishSubject.create() override val backClicked: Subject<Unit> = PublishSubject.create() @Inject lateinit var blockedMessagesAdapter: BlockedMessagesAdapter @Inject lateinit var blockingDialog: BlockingDialog @Inject lateinit var colors: Colors @Inject lateinit var context: Context @Inject override lateinit var presenter: BlockedMessagesPresenter init { Loading @@ -43,7 +59,6 @@ class BlockedMessagesController : QkController<BlockedMessagesView, BlockedMessa override fun onViewCreated() { super.onViewCreated() blockedMessagesAdapter.emptyView = empty conversations.adapter = blockedMessagesAdapter } Loading @@ -53,10 +68,55 @@ class BlockedMessagesController : QkController<BlockedMessagesView, BlockedMessa presenter.bindIntents(this) setTitle(R.string.blocked_messages_title) showBackButton(true) setHasOptionsMenu(true) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { super.onCreateOptionsMenu(menu, inflater) inflater.inflate(R.menu.blocked_messages, menu) menuReadyIntent.onNext(Unit) } override fun onOptionsItemSelected(item: MenuItem): Boolean { optionsItemIntent.onNext(item.itemId) return true } override fun handleBack(): Boolean { backClicked.onNext(Unit) return true } override fun render(state: BlockedMessagesState) { blockedMessagesAdapter.updateData(state.data) themedActivity?.toolbar?.menu?.findItem(R.id.block)?.isVisible = state.selected > 0 themedActivity?.toolbar?.menu?.findItem(R.id.delete)?.isVisible = state.selected > 0 setTitle(when (state.selected) { 0 -> context.getString(R.string.blocked_messages_title) else -> context.getString(R.string.main_title_selected, state.selected) }) } override fun clearSelection() = blockedMessagesAdapter.clearSelection() override fun showBlockingDialog(conversations: List<Long>, block: Boolean) { blockingDialog.show(activity!!, conversations, block) } override fun showDeleteDialog(conversations: List<Long>) { val count = conversations.size AlertDialog.Builder(activity) .setTitle(R.string.dialog_delete_title) .setMessage(resources?.getQuantityString(R.plurals.dialog_delete_message, count, count)) .setPositiveButton(R.string.button_delete) { _, _ -> confirmDeleteIntent.onNext(conversations) } .setNegativeButton(R.string.button_cancel, null) .show() } override fun goBack() { router.popCurrentController() } } presentation/src/main/java/com/moez/QKSMS/feature/blocking/messages/BlockedMessagesPresenter.kt +47 −0 Original line number Diff line number Diff line Loading @@ -18,15 +18,21 @@ */ package com.moez.QKSMS.feature.blocking.messages import com.moez.QKSMS.R import com.moez.QKSMS.blocking.BlockingClient import com.moez.QKSMS.common.Navigator import com.moez.QKSMS.common.base.QkPresenter import com.moez.QKSMS.interactor.DeleteConversations import com.moez.QKSMS.repository.ConversationRepository import com.uber.autodispose.android.lifecycle.scope import com.uber.autodispose.autoDisposable import io.reactivex.rxkotlin.withLatestFrom import javax.inject.Inject class BlockedMessagesPresenter @Inject constructor( conversationRepo: ConversationRepository, private val blockingClient: BlockingClient, private val deleteConversations: DeleteConversations, private val navigator: Navigator ) : QkPresenter<BlockedMessagesView, BlockedMessagesState>(BlockedMessagesState( data = conversationRepo.getBlockedConversations() Loading @@ -35,9 +41,50 @@ class BlockedMessagesPresenter @Inject constructor( override fun bindIntents(view: BlockedMessagesView) { super.bindIntents(view) view.menuReadyIntent .autoDisposable(view.scope()) .subscribe { newState { copy() } } view.optionsItemIntent .withLatestFrom(view.selectionChanges) { itemId, conversations -> when (itemId) { R.id.block -> { view.showBlockingDialog(conversations, false) view.clearSelection() } R.id.delete -> { view.showDeleteDialog(conversations) } } } .autoDisposable(view.scope()) .subscribe() view.confirmDeleteIntent .autoDisposable(view.scope()) .subscribe { conversations -> deleteConversations.execute(conversations) view.clearSelection() } view.conversationClicks .autoDisposable(view.scope()) .subscribe { threadId -> navigator.showConversation(threadId) } view.selectionChanges .autoDisposable(view.scope()) .subscribe { selection -> newState { copy(selected = selection.size) } } view.backClicked .withLatestFrom(view.selectionChanges) { _, selection -> when (selection.size) { 0 -> view.goBack() else -> view.clearSelection() } } .autoDisposable(view.scope()) .subscribe() } } presentation/src/main/java/com/moez/QKSMS/feature/blocking/messages/BlockedMessagesState.kt +2 −1 Original line number Diff line number Diff line Loading @@ -22,5 +22,6 @@ import com.moez.QKSMS.model.Conversation import io.realm.RealmResults data class BlockedMessagesState( val data: RealmResults<Conversation>? = null val data: RealmResults<Conversation>? = null, val selected: Int = 0 ) Loading
presentation/src/main/java/com/moez/QKSMS/common/base/QkRealmAdapter.kt +1 −1 Original line number Diff line number Diff line Loading @@ -48,7 +48,7 @@ abstract class QkRealmAdapter<T : RealmModel> : RealmRecyclerViewAdapter<T, QkVi emptyView?.setVisible(data.isLoaded && data.isEmpty()) } val selectionChanges: Subject<List<Long>> = BehaviorSubject.create() val selectionChanges: Subject<List<Long>> = BehaviorSubject.createDefault(listOf()) private var selection = listOf<Long>() Loading
presentation/src/main/java/com/moez/QKSMS/feature/blocking/messages/BlockedMessagesAdapter.kt +12 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,16 @@ class BlockedMessagesAdapter @Inject constructor() : QkRealmAdapter<Conversation return QkViewHolder(view).apply { view.setOnClickListener { val conversation = getItem(adapterPosition) ?: return@setOnClickListener clicks.onNext(conversation.id) when (toggleSelection(conversation.id, false)) { true -> view.isActivated = isSelected(conversation.id) false -> clicks.onNext(conversation.id) } } view.setOnLongClickListener { val conversation = getItem(adapterPosition) ?: return@setOnLongClickListener true toggleSelection(conversation.id) view.isActivated = isSelected(conversation.id) true } } } Loading @@ -46,6 +55,8 @@ class BlockedMessagesAdapter @Inject constructor() : QkRealmAdapter<Conversation val conversation = getItem(position) ?: return val view = holder.containerView view.isActivated = isSelected(conversation.id) view.avatars.contacts = conversation.recipients view.title.collapseEnabled = conversation.recipients.size > 1 view.title.text = conversation.getTitle() Loading
presentation/src/main/java/com/moez/QKSMS/feature/blocking/messages/BlockedMessagesController.kt +61 −1 Original line number Diff line number Diff line Loading @@ -18,21 +18,37 @@ */ package com.moez.QKSMS.feature.blocking.messages import android.app.AlertDialog import android.content.Context import android.view.Menu import android.view.MenuInflater import android.view.MenuItem import android.view.View import com.moez.QKSMS.R import com.moez.QKSMS.common.base.QkController import com.moez.QKSMS.common.util.Colors import com.moez.QKSMS.feature.blocking.BlockingDialog import com.moez.QKSMS.injection.appComponent import io.reactivex.subjects.PublishSubject import io.reactivex.subjects.Subject import kotlinx.android.synthetic.main.blocked_messages_controller.* import kotlinx.android.synthetic.main.container_activity.* import javax.inject.Inject class BlockedMessagesController : QkController<BlockedMessagesView, BlockedMessagesState, BlockedMessagesPresenter>(), BlockedMessagesView { override val menuReadyIntent: Subject<Unit> = PublishSubject.create() override val optionsItemIntent: Subject<Int> = PublishSubject.create() override val conversationClicks by lazy { blockedMessagesAdapter.clicks } override val selectionChanges by lazy { blockedMessagesAdapter.selectionChanges } override val confirmDeleteIntent: Subject<List<Long>> = PublishSubject.create() override val backClicked: Subject<Unit> = PublishSubject.create() @Inject lateinit var blockedMessagesAdapter: BlockedMessagesAdapter @Inject lateinit var blockingDialog: BlockingDialog @Inject lateinit var colors: Colors @Inject lateinit var context: Context @Inject override lateinit var presenter: BlockedMessagesPresenter init { Loading @@ -43,7 +59,6 @@ class BlockedMessagesController : QkController<BlockedMessagesView, BlockedMessa override fun onViewCreated() { super.onViewCreated() blockedMessagesAdapter.emptyView = empty conversations.adapter = blockedMessagesAdapter } Loading @@ -53,10 +68,55 @@ class BlockedMessagesController : QkController<BlockedMessagesView, BlockedMessa presenter.bindIntents(this) setTitle(R.string.blocked_messages_title) showBackButton(true) setHasOptionsMenu(true) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { super.onCreateOptionsMenu(menu, inflater) inflater.inflate(R.menu.blocked_messages, menu) menuReadyIntent.onNext(Unit) } override fun onOptionsItemSelected(item: MenuItem): Boolean { optionsItemIntent.onNext(item.itemId) return true } override fun handleBack(): Boolean { backClicked.onNext(Unit) return true } override fun render(state: BlockedMessagesState) { blockedMessagesAdapter.updateData(state.data) themedActivity?.toolbar?.menu?.findItem(R.id.block)?.isVisible = state.selected > 0 themedActivity?.toolbar?.menu?.findItem(R.id.delete)?.isVisible = state.selected > 0 setTitle(when (state.selected) { 0 -> context.getString(R.string.blocked_messages_title) else -> context.getString(R.string.main_title_selected, state.selected) }) } override fun clearSelection() = blockedMessagesAdapter.clearSelection() override fun showBlockingDialog(conversations: List<Long>, block: Boolean) { blockingDialog.show(activity!!, conversations, block) } override fun showDeleteDialog(conversations: List<Long>) { val count = conversations.size AlertDialog.Builder(activity) .setTitle(R.string.dialog_delete_title) .setMessage(resources?.getQuantityString(R.plurals.dialog_delete_message, count, count)) .setPositiveButton(R.string.button_delete) { _, _ -> confirmDeleteIntent.onNext(conversations) } .setNegativeButton(R.string.button_cancel, null) .show() } override fun goBack() { router.popCurrentController() } }
presentation/src/main/java/com/moez/QKSMS/feature/blocking/messages/BlockedMessagesPresenter.kt +47 −0 Original line number Diff line number Diff line Loading @@ -18,15 +18,21 @@ */ package com.moez.QKSMS.feature.blocking.messages import com.moez.QKSMS.R import com.moez.QKSMS.blocking.BlockingClient import com.moez.QKSMS.common.Navigator import com.moez.QKSMS.common.base.QkPresenter import com.moez.QKSMS.interactor.DeleteConversations import com.moez.QKSMS.repository.ConversationRepository import com.uber.autodispose.android.lifecycle.scope import com.uber.autodispose.autoDisposable import io.reactivex.rxkotlin.withLatestFrom import javax.inject.Inject class BlockedMessagesPresenter @Inject constructor( conversationRepo: ConversationRepository, private val blockingClient: BlockingClient, private val deleteConversations: DeleteConversations, private val navigator: Navigator ) : QkPresenter<BlockedMessagesView, BlockedMessagesState>(BlockedMessagesState( data = conversationRepo.getBlockedConversations() Loading @@ -35,9 +41,50 @@ class BlockedMessagesPresenter @Inject constructor( override fun bindIntents(view: BlockedMessagesView) { super.bindIntents(view) view.menuReadyIntent .autoDisposable(view.scope()) .subscribe { newState { copy() } } view.optionsItemIntent .withLatestFrom(view.selectionChanges) { itemId, conversations -> when (itemId) { R.id.block -> { view.showBlockingDialog(conversations, false) view.clearSelection() } R.id.delete -> { view.showDeleteDialog(conversations) } } } .autoDisposable(view.scope()) .subscribe() view.confirmDeleteIntent .autoDisposable(view.scope()) .subscribe { conversations -> deleteConversations.execute(conversations) view.clearSelection() } view.conversationClicks .autoDisposable(view.scope()) .subscribe { threadId -> navigator.showConversation(threadId) } view.selectionChanges .autoDisposable(view.scope()) .subscribe { selection -> newState { copy(selected = selection.size) } } view.backClicked .withLatestFrom(view.selectionChanges) { _, selection -> when (selection.size) { 0 -> view.goBack() else -> view.clearSelection() } } .autoDisposable(view.scope()) .subscribe() } }
presentation/src/main/java/com/moez/QKSMS/feature/blocking/messages/BlockedMessagesState.kt +2 −1 Original line number Diff line number Diff line Loading @@ -22,5 +22,6 @@ import com.moez.QKSMS.model.Conversation import io.realm.RealmResults data class BlockedMessagesState( val data: RealmResults<Conversation>? = null val data: RealmResults<Conversation>? = null, val selected: Int = 0 )