diff --git a/data/src/main/java/com/moez/QKSMS/blocking/BlockingManager.kt b/data/src/main/java/com/moez/QKSMS/blocking/BlockingManager.kt new file mode 100644 index 00000000..2e10071e --- /dev/null +++ b/data/src/main/java/com/moez/QKSMS/blocking/BlockingManager.kt @@ -0,0 +1,37 @@ +package com.moez.QKSMS.blocking + +import com.moez.QKSMS.util.Preferences +import io.reactivex.Completable +import io.reactivex.Single +import javax.inject.Inject +import javax.inject.Singleton + +/** + * Delegates requests to the active blocking client + */ +@Singleton +class BlockingManager @Inject constructor( + private val prefs: Preferences, + private val callControlBlockingClient: CallControlBlockingClient, + private val qkBlockingClient: QkBlockingClient, + private val shouldIAnswerBlockingClient: ShouldIAnswerBlockingClient +) : BlockingClient { + + private val client: BlockingClient + get() = when (prefs.blockingManager.get()) { + Preferences.BLOCKING_MANAGER_SIA -> shouldIAnswerBlockingClient + Preferences.BLOCKING_MANAGER_CC -> callControlBlockingClient + else -> qkBlockingClient + } + + override fun isBlocked(address: String): Single = client.isBlocked(address) + + override fun canBlock(): Boolean = client.canBlock() + + override fun block(addresses: List): Completable = client.block(addresses) + + override fun canUnblock(): Boolean = client.canUnblock() + + override fun unblock(addresses: List): Completable = client.unblock(addresses) + +} diff --git a/data/src/main/java/com/moez/QKSMS/blocking/CallControlBlockingClient.kt b/data/src/main/java/com/moez/QKSMS/blocking/CallControlBlockingClient.kt index 42618930..2c8dfeb1 100644 --- a/data/src/main/java/com/moez/QKSMS/blocking/CallControlBlockingClient.kt +++ b/data/src/main/java/com/moez/QKSMS/blocking/CallControlBlockingClient.kt @@ -55,11 +55,14 @@ class CallControlBlockingClient @Inject constructor( override fun canBlock(): Boolean = true - override fun block(address: String): Completable = Completable.fromCallable { - CallControl.report(context, CallControl.Report(address)) + override fun block(addresses: List): Completable = Completable.fromCallable { + val reports = addresses.map { CallControl.Report(it) } + CallControl.report(context, arrayListOf().apply { addAll(reports) }) } - override fun unblock(address: String): Completable = Completable.fromCallable { + override fun unblock(addresses: List): Completable = Completable.fromCallable { + // Only show a particular address if we're only unblocking that one + val address = addresses.takeIf { it.size == 1 }?.first() CallControl.openBlockedList(context, address) } diff --git a/data/src/main/java/com/moez/QKSMS/blocking/QkBlockingClient.kt b/data/src/main/java/com/moez/QKSMS/blocking/QkBlockingClient.kt index 7fbde8f9..1e361070 100644 --- a/data/src/main/java/com/moez/QKSMS/blocking/QkBlockingClient.kt +++ b/data/src/main/java/com/moez/QKSMS/blocking/QkBlockingClient.kt @@ -19,6 +19,7 @@ package com.moez.QKSMS.blocking import android.content.Context +import android.content.Intent import android.os.Build import android.provider.BlockedNumberContract import android.telecom.TelecomManager @@ -45,11 +46,12 @@ class QkBlockingClient @Inject constructor(private val context: Context) : Block override fun canBlock(): Boolean = Build.VERSION.SDK_INT < 24 - override fun block(address: String): Completable = Completable.fromCallable { + override fun block(addresses: List): Completable = Completable.fromCallable { when { Build.VERSION.SDK_INT >= 24 -> { val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager val intent = telecomManager.createManageBlockedNumbersIntent() + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent) } @@ -58,7 +60,7 @@ class QkBlockingClient @Inject constructor(private val context: Context) : Block .max("id")?.toLong() ?: -1 realm.executeTransaction { - realm.insert(BlockedNumber(maxId + 1, address)) + realm.insert(addresses.mapIndexed { index, address -> BlockedNumber(maxId + 1 + index, address) }) } } } @@ -66,15 +68,19 @@ class QkBlockingClient @Inject constructor(private val context: Context) : Block override fun canUnblock(): Boolean = true - override fun unblock(address: String): Completable = Completable.fromCallable { + override fun unblock(addresses: List): Completable = Completable.fromCallable { when { - Build.VERSION.SDK_INT >= 24 -> BlockedNumberContract.unblock(context, address) + Build.VERSION.SDK_INT >= 24 -> addresses.forEach { address -> + BlockedNumberContract.unblock(context, address) + } else -> Realm.getDefaultInstance().use { realm -> val ids = realm .where(BlockedNumber::class.java) .findAll() - .filter { number -> PhoneNumberUtils.compare(number.address, address) } + .filter { number -> + addresses.any { address -> PhoneNumberUtils.compare(number.address, address) } + } .map { number -> number.id } .toLongArray() diff --git a/data/src/main/java/com/moez/QKSMS/blocking/ShouldIAnswerBlockingClient.kt b/data/src/main/java/com/moez/QKSMS/blocking/ShouldIAnswerBlockingClient.kt index 0f0e564a..bd0270ab 100644 --- a/data/src/main/java/com/moez/QKSMS/blocking/ShouldIAnswerBlockingClient.kt +++ b/data/src/main/java/com/moez/QKSMS/blocking/ShouldIAnswerBlockingClient.kt @@ -56,9 +56,9 @@ class ShouldIAnswerBlockingClient @Inject constructor( return Binder(context, prefs, address).isBlocked() } - override fun block(address: String): Completable = Completable.fromCallable { showSia() } + override fun block(addresses: List): Completable = Completable.fromCallable { showSia() } - override fun unblock(address: String): Completable = Completable.fromCallable { showSia() } + override fun unblock(addresses: List): Completable = Completable.fromCallable { showSia() } private fun showSia() { val pm = context.packageManager diff --git a/data/src/main/java/com/moez/QKSMS/repository/ConversationRepositoryImpl.kt b/data/src/main/java/com/moez/QKSMS/repository/ConversationRepositoryImpl.kt index 52b1d117..2b6148e8 100644 --- a/data/src/main/java/com/moez/QKSMS/repository/ConversationRepositoryImpl.kt +++ b/data/src/main/java/com/moez/QKSMS/repository/ConversationRepositoryImpl.kt @@ -141,6 +141,13 @@ class ConversationRepositoryImpl @Inject constructor( .findFirst() } + override fun getConversations(vararg threadIds: Long): RealmResults { + return Realm.getDefaultInstance() + .where(Conversation::class.java) + .anyOf("id", threadIds) + .findAll() + } + override fun getThreadId(recipient: String): Long? { return getThreadId(listOf(recipient)) } diff --git a/domain/src/main/java/com/moez/QKSMS/blocking/BlockingClient.kt b/domain/src/main/java/com/moez/QKSMS/blocking/BlockingClient.kt index 57741da5..b7d2b5d3 100644 --- a/domain/src/main/java/com/moez/QKSMS/blocking/BlockingClient.kt +++ b/domain/src/main/java/com/moez/QKSMS/blocking/BlockingClient.kt @@ -35,9 +35,9 @@ interface BlockingClient { fun canBlock(): Boolean = false /** - * Blocks the number or opens the manager + * Blocks the numbers or opens the manager */ - fun block(address: String): Completable + fun block(addresses: List): Completable /** * Returns true if the client is capable of unblocking the address in the manager without any @@ -46,8 +46,8 @@ interface BlockingClient { fun canUnblock(): Boolean = false /** - * Unblocks the number or opens the manager + * Unblocks the numbers or opens the manager */ - fun unblock(address: String): Completable + fun unblock(addresses: List): Completable } \ No newline at end of file diff --git a/domain/src/main/java/com/moez/QKSMS/repository/ConversationRepository.kt b/domain/src/main/java/com/moez/QKSMS/repository/ConversationRepository.kt index bf07859f..d7dc1f80 100644 --- a/domain/src/main/java/com/moez/QKSMS/repository/ConversationRepository.kt +++ b/domain/src/main/java/com/moez/QKSMS/repository/ConversationRepository.kt @@ -43,6 +43,11 @@ interface ConversationRepository { fun getConversation(threadId: Long): Conversation? + /** + * Returns all conversations with an id in [threadIds] + */ + fun getConversations(vararg threadIds: Long): RealmResults + fun getThreadId(recipient: String): Long? fun getThreadId(recipients: Collection): Long? diff --git a/domain/src/main/java/com/moez/QKSMS/util/Preferences.kt b/domain/src/main/java/com/moez/QKSMS/util/Preferences.kt index e2295120..27174846 100644 --- a/domain/src/main/java/com/moez/QKSMS/util/Preferences.kt +++ b/domain/src/main/java/com/moez/QKSMS/util/Preferences.kt @@ -60,6 +60,10 @@ class Preferences @Inject constructor(private val rxPrefs: RxSharedPreferences) const val SWIPE_ACTION_CALL = 3 const val SWIPE_ACTION_READ = 4 const val SWIPE_ACTION_UNREAD = 5 + + const val BLOCKING_MANAGER_QKSMS = 0 + const val BLOCKING_MANAGER_CC = 1 + const val BLOCKING_MANAGER_SIA = 2 } // Internal @@ -76,6 +80,7 @@ class Preferences @Inject constructor(private val rxPrefs: RxSharedPreferences) val black = rxPrefs.getBoolean("black", false) val systemFont = rxPrefs.getBoolean("systemFont", false) val textSize = rxPrefs.getInteger("textSize", TEXT_SIZE_NORMAL) + val blockingManager = rxPrefs.getInteger("blockingManager", BLOCKING_MANAGER_QKSMS) val callControl = rxPrefs.getBoolean("callControl", false) val sia = rxPrefs.getBoolean("sia", false) val drop = rxPrefs.getBoolean("drop", false) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedActivity.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedActivity.kt index 1619b8ca..554cdb9c 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedActivity.kt @@ -18,7 +18,6 @@ */ package com.moez.QKSMS.feature.blocked -import android.app.AlertDialog import android.os.Bundle import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProviders @@ -26,8 +25,6 @@ import com.jakewharton.rxbinding2.view.clicks import com.moez.QKSMS.R import com.moez.QKSMS.common.base.QkThemedActivity import dagger.android.AndroidInjection -import io.reactivex.subjects.PublishSubject -import io.reactivex.subjects.Subject import kotlinx.android.synthetic.main.blocked_activity.* import kotlinx.android.synthetic.main.settings_switch_widget.view.* import javax.inject.Inject @@ -40,8 +37,7 @@ class BlockedActivity : QkThemedActivity(), BlockedView { override val ccClickedIntent by lazy { callControl.clicks() } override val siaClickedIntent by lazy { shouldIAnswer.clicks() } override val dropClickedIntent by lazy { drop.clicks() } - override val unblockIntent by lazy { blockedAdapter.unblock } - override val confirmUnblockIntent: Subject = PublishSubject.create() + override val conversationClicks by lazy { blockedAdapter.clicks } private val viewModel by lazy { ViewModelProviders.of(this, viewModelFactory)[BlockedViewModel::class.java] } @@ -65,13 +61,4 @@ class BlockedActivity : QkThemedActivity(), BlockedView { blockedAdapter.updateData(state.data) } - override fun showUnblockDialog(threadId: Long) { - AlertDialog.Builder(this) - .setTitle(R.string.blocked_unblock_dialog_title) - .setMessage(R.string.blocked_unblock_dialog_message) - .setPositiveButton(R.string.button_unblock) { _, _ -> confirmUnblockIntent.onNext(threadId) } - .setNegativeButton(R.string.button_cancel, null) - .show() - } - } \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedAdapter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedAdapter.kt index f6c1df30..8b03e48a 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedAdapter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedAdapter.kt @@ -30,14 +30,14 @@ import javax.inject.Inject class BlockedAdapter @Inject constructor() : QkRealmAdapter() { - val unblock: PublishSubject = PublishSubject.create() + val clicks: PublishSubject = PublishSubject.create() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QkViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.blocked_list_item, parent, false) return QkViewHolder(view).apply { view.setOnClickListener { val conversation = getItem(adapterPosition) ?: return@setOnClickListener - unblock.onNext(conversation.id) + clicks.onNext(conversation.id) } } } @@ -47,6 +47,7 @@ class BlockedAdapter @Inject constructor() : QkRealmAdapter() { val view = holder.containerView view.avatars.contacts = conversation.recipients + view.title.collapseEnabled = conversation.recipients.size > 1 view.title.text = conversation.getTitle() } diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedView.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedView.kt index 33a74faf..9e953852 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedView.kt @@ -26,9 +26,6 @@ interface BlockedView : QkView { val ccClickedIntent: Observable<*> val siaClickedIntent: Observable<*> val dropClickedIntent: Observable<*> - val unblockIntent: Observable - val confirmUnblockIntent: Observable + val conversationClicks: Observable - fun showUnblockDialog(threadId: Long) - -} \ No newline at end of file +} diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedViewModel.kt index e2559710..ea310e87 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockedViewModel.kt @@ -22,7 +22,6 @@ import android.content.Context import com.moez.QKSMS.common.Navigator import com.moez.QKSMS.common.base.QkViewModel import com.moez.QKSMS.common.util.extensions.isInstalled -import com.moez.QKSMS.interactor.MarkUnblocked import com.moez.QKSMS.manager.AnalyticsManager import com.moez.QKSMS.repository.ConversationRepository import com.moez.QKSMS.util.Preferences @@ -35,7 +34,6 @@ class BlockedViewModel @Inject constructor( private val context: Context, private val analytics: AnalyticsManager, private val conversationRepo: ConversationRepository, - private val markUnblocked: MarkUnblocked, private val navigator: Navigator, private val prefs: Preferences ) : QkViewModel(BlockedState()) { @@ -93,15 +91,9 @@ class BlockedViewModel @Inject constructor( .autoDisposable(view.scope()) .subscribe { prefs.drop.set(!prefs.drop.get()) } - // Show confirm unblock conversation dialog - view.unblockIntent + view.conversationClicks .autoDisposable(view.scope()) - .subscribe { threadId -> view.showUnblockDialog(threadId) } - - // Unblock conversation - view.confirmUnblockIntent - .autoDisposable(view.scope()) - .subscribe { threadId -> markUnblocked.execute(listOf(threadId)) } + .subscribe { threadId -> navigator.showConversation(threadId) } } -} \ No newline at end of file +} diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockingDialog.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockingDialog.kt new file mode 100644 index 00000000..b2f681ce --- /dev/null +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocked/BlockingDialog.kt @@ -0,0 +1,75 @@ +package com.moez.QKSMS.feature.blocked + +import android.app.Activity +import android.app.AlertDialog +import android.content.Context +import com.moez.QKSMS.R +import com.moez.QKSMS.blocking.BlockingClient +import com.moez.QKSMS.interactor.MarkBlocked +import com.moez.QKSMS.interactor.MarkUnblocked +import com.moez.QKSMS.repository.ConversationRepository +import com.moez.QKSMS.util.Preferences +import javax.inject.Inject + +// TODO: Once we have a custom dialog based on conductor, turn this into a controller +class BlockingDialog @Inject constructor( + private val blockingManager: BlockingClient, + private val context: Context, + private val conversationRepo: ConversationRepository, + private val prefs: Preferences, + private val markBlocked: MarkBlocked, + private val markUnblocked: MarkUnblocked +) { + + fun show(activity: Activity, conversationIds: List, block: Boolean) { + val addresses = conversationIds.toLongArray() + .let(conversationRepo::getConversations) + .flatMap { conversation -> conversation.recipients } + .map { it.address } + .distinct() + + // If we can block/unblock in the external manager, then just fire that off and exit + if (block) { + markBlocked.execute(conversationIds) + if (blockingManager.canBlock()) { + blockingManager.block(addresses).subscribe() + return + } + } else { + markUnblocked.execute(conversationIds) + if (blockingManager.canUnblock()) { + blockingManager.unblock(addresses).subscribe() + return + } + } + + val res = when (block) { + true -> R.plurals.settings_blocking_block_external + false -> R.plurals.settings_blocking_unblock_external + } + + val manager = context.getString(when (prefs.blockingManager.get()) { + Preferences.BLOCKING_MANAGER_SIA -> R.string.settings_should_i_answer_title + Preferences.BLOCKING_MANAGER_CC -> R.string.settings_call_control_title + else -> R.string.settings_blocking_manager_android + }) + + val message = context.resources.getQuantityString(res, addresses.size, manager) + + // Otherwise, show a dialog asking the user if they want to be directed to the external + // blocking manager + AlertDialog.Builder(activity) + .setTitle(R.string.main_menu_block) + .setMessage(message) + .setPositiveButton(R.string.button_yes) { _, _ -> + when (block) { + true -> blockingManager.block(addresses) + false -> blockingManager.unblock(addresses) + }.subscribe() + } + .setNegativeButton(R.string.button_cancel) { _, _ -> } + .create() + .show() + } + +} diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt index f0de025e..0bfe0614 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt @@ -30,6 +30,7 @@ import com.moez.QKSMS.common.util.extensions.animateLayoutChanges import com.moez.QKSMS.common.util.extensions.scrapViews import com.moez.QKSMS.common.util.extensions.setVisible import com.moez.QKSMS.common.widget.FieldDialog +import com.moez.QKSMS.feature.blocked.BlockingDialog import com.moez.QKSMS.feature.conversationinfo.injection.ConversationInfoModule import com.moez.QKSMS.feature.themepicker.ThemePickerController import com.moez.QKSMS.injection.appComponent @@ -46,6 +47,7 @@ class ConversationInfoController( ) : QkController(), ConversationInfoView { @Inject override lateinit var presenter: ConversationInfoPresenter + @Inject lateinit var blockingDialog: BlockingDialog @Inject lateinit var navigator: Navigator @Inject lateinit var recipientAdapter: ConversationRecipientAdapter @Inject lateinit var mediaAdapter: ConversationMediaAdapter @@ -142,6 +144,10 @@ class ConversationInfoController( .popChangeHandler(QkChangeHandler())) } + override fun showBlockingDialog(conversations: List, block: Boolean) { + blockingDialog.show(activity!!, conversations, block) + } + override fun showDeleteDialog() { AlertDialog.Builder(activity!!) .setTitle(R.string.dialog_delete_title) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt index 57c3999e..313222f0 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt @@ -23,9 +23,7 @@ import com.moez.QKSMS.common.base.QkPresenter import com.moez.QKSMS.extensions.asObservable import com.moez.QKSMS.interactor.DeleteConversations import com.moez.QKSMS.interactor.MarkArchived -import com.moez.QKSMS.interactor.MarkBlocked import com.moez.QKSMS.interactor.MarkUnarchived -import com.moez.QKSMS.interactor.MarkUnblocked import com.moez.QKSMS.manager.PermissionManager import com.moez.QKSMS.model.Conversation import com.moez.QKSMS.repository.ConversationRepository @@ -46,8 +44,6 @@ class ConversationInfoPresenter @Inject constructor( private val deleteConversations: DeleteConversations, private val markArchived: MarkArchived, private val markUnarchived: MarkUnarchived, - private val markBlocked: MarkBlocked, - private val markUnblocked: MarkUnblocked, private val navigator: Navigator, private val permissionManager: PermissionManager ) : QkPresenter( @@ -71,8 +67,6 @@ class ConversationInfoPresenter @Inject constructor( disposables += markArchived disposables += markUnarchived - disposables += markBlocked - disposables += markUnblocked disposables += deleteConversations // Update the recipients whenever they change @@ -145,12 +139,7 @@ class ConversationInfoPresenter @Inject constructor( view.blockClicks() .withLatestFrom(conversation) { _, conversation -> conversation } .autoDisposable(view.scope()) - .subscribe { conversation -> - when (conversation.blocked) { - true -> markUnblocked.execute(listOf(conversation.id)) - false -> markBlocked.execute(listOf(conversation.id)) - } - } + .subscribe { conversation -> view.showBlockingDialog(listOf(conversation.id), !conversation.blocked) } // Show the delete confirmation dialog view.deleteClicks() diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoView.kt b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoView.kt index eeeb0e91..58e575c9 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoView.kt @@ -34,6 +34,7 @@ interface ConversationInfoView : QkViewContract { fun showNameDialog(name: String) fun showThemePicker(threadId: Long) + fun showBlockingDialog(conversations: List, block: Boolean) fun showDeleteDialog() } \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt index ce50e6f3..40071242 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt @@ -51,6 +51,7 @@ import com.moez.QKSMS.common.util.extensions.scrapViews import com.moez.QKSMS.common.util.extensions.setBackgroundTint import com.moez.QKSMS.common.util.extensions.setTint import com.moez.QKSMS.common.util.extensions.setVisible +import com.moez.QKSMS.feature.blocked.BlockingDialog import com.moez.QKSMS.feature.changelog.ChangelogDialog import com.moez.QKSMS.feature.conversations.ConversationItemTouchCallback import com.moez.QKSMS.feature.conversations.ConversationsAdapter @@ -71,6 +72,7 @@ import javax.inject.Inject class MainActivity : QkThemedActivity(), MainView { + @Inject lateinit var blockingDialog: BlockingDialog @Inject lateinit var disposables: CompositeDisposable @Inject lateinit var navigator: Navigator @Inject lateinit var conversationsAdapter: ConversationsAdapter @@ -156,7 +158,8 @@ class MainActivity : QkThemedActivity(), MainView { .autoDisposable(scope()) .subscribe { theme -> // Set the color for the drawer icons - val states = arrayOf(intArrayOf(android.R.attr.state_activated), intArrayOf(-android.R.attr.state_activated)) + val states = arrayOf(intArrayOf(android.R.attr.state_activated), + intArrayOf(-android.R.attr.state_activated)) resolveThemeColor(android.R.attr.textColorSecondary) .let { textSecondary -> ColorStateList(states, intArrayOf(theme.theme, textSecondary)) } .let { tintList -> @@ -268,8 +271,10 @@ class MainActivity : QkThemedActivity(), MainView { inbox.isActivated = state.page is Inbox archived.isActivated = state.page is Archived - if (drawerLayout.isDrawerOpen(GravityCompat.START) && !state.drawerOpen) drawerLayout.closeDrawer(GravityCompat.START) - else if (!drawerLayout.isDrawerVisible(GravityCompat.START) && state.drawerOpen) drawerLayout.openDrawer(GravityCompat.START) + if (drawerLayout.isDrawerOpen(GravityCompat.START) && !state.drawerOpen) drawerLayout.closeDrawer( + GravityCompat.START) + else if (!drawerLayout.isDrawerVisible(GravityCompat.START) && state.drawerOpen) drawerLayout.openDrawer( + GravityCompat.START) when (state.syncing) { is SyncRepository.SyncProgress.Idle -> { @@ -341,6 +346,10 @@ class MainActivity : QkThemedActivity(), MainView { conversationsAdapter.clearSelection() } + override fun showBlockingDialog(conversations: List, block: Boolean) { + blockingDialog.show(this, conversations, block) + } + override fun showDeleteDialog(conversations: List) { val count = conversations.size AlertDialog.Builder(this) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainView.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainView.kt index 17698164..873aa69c 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainView.kt @@ -46,6 +46,7 @@ interface MainView : QkView { fun requestPermissions() fun clearSearch() fun clearSelection() + fun showBlockingDialog(conversations: List, block: Boolean) fun showDeleteDialog(conversations: List) fun showChangelog(changelog: ChangelogManager.Changelog) fun showArchivedSnackbar() diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt index 1f2b10bd..645ee60c 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt @@ -27,7 +27,6 @@ import com.moez.QKSMS.extensions.removeAccents import com.moez.QKSMS.interactor.DeleteConversations import com.moez.QKSMS.interactor.MarkAllSeen import com.moez.QKSMS.interactor.MarkArchived -import com.moez.QKSMS.interactor.MarkBlocked import com.moez.QKSMS.interactor.MarkPinned import com.moez.QKSMS.interactor.MarkRead import com.moez.QKSMS.interactor.MarkUnarchived @@ -64,7 +63,6 @@ class MainViewModel @Inject constructor( private val conversationRepo: ConversationRepository, private val deleteConversations: DeleteConversations, private val markArchived: MarkArchived, - private val markBlocked: MarkBlocked, private val markPinned: MarkPinned, private val markRead: MarkRead, private val markUnarchived: MarkUnarchived, @@ -319,7 +317,7 @@ class MainViewModel @Inject constructor( view.optionsItemIntent .filter { itemId -> itemId == R.id.block } .withLatestFrom(view.conversationsSelectedIntent) { _, conversations -> - markBlocked.execute(conversations) + view.showBlockingDialog(conversations, true) view.clearSelection() } .autoDisposable(view.scope()) diff --git a/presentation/src/main/java/com/moez/QKSMS/injection/AppModule.kt b/presentation/src/main/java/com/moez/QKSMS/injection/AppModule.kt index 1067969f..d2d7a572 100644 --- a/presentation/src/main/java/com/moez/QKSMS/injection/AppModule.kt +++ b/presentation/src/main/java/com/moez/QKSMS/injection/AppModule.kt @@ -26,9 +26,7 @@ import android.preference.PreferenceManager import androidx.lifecycle.ViewModelProvider import com.f2prateek.rx.preferences2.RxSharedPreferences import com.moez.QKSMS.blocking.BlockingClient -import com.moez.QKSMS.blocking.CallControlBlockingClient -import com.moez.QKSMS.blocking.QkBlockingClient -import com.moez.QKSMS.blocking.ShouldIAnswerBlockingClient +import com.moez.QKSMS.blocking.BlockingManager import com.moez.QKSMS.common.ViewModelFactory import com.moez.QKSMS.common.util.NotificationManagerImpl import com.moez.QKSMS.common.util.ShortcutManagerImpl @@ -78,7 +76,6 @@ import com.moez.QKSMS.repository.ScheduledMessageRepository import com.moez.QKSMS.repository.ScheduledMessageRepositoryImpl import com.moez.QKSMS.repository.SyncRepository import com.moez.QKSMS.repository.SyncRepositoryImpl -import com.moez.QKSMS.util.Preferences import com.squareup.moshi.Moshi import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import dagger.Module @@ -132,16 +129,7 @@ class AppModule(private var application: Application) { fun provideAnalyticsManager(manager: AnalyticsManagerImpl): AnalyticsManager = manager @Provides - fun externalBlockingManager( - callControl: CallControlBlockingClient, - sia: ShouldIAnswerBlockingClient, - qksms: QkBlockingClient, - prefs: Preferences - ): BlockingClient = when { - prefs.callControl.get() -> callControl - prefs.sia.get() -> sia - else -> qksms - } + fun blockingClient(manager: BlockingManager): BlockingClient = manager @Provides fun changelogManager(manager: ChangelogManagerImpl): ChangelogManager = manager diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index 3957e831..bfba5b13 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -223,8 +223,15 @@ Blocking Blocking Manager Built-in blocking functionality in QKSMS - Would you also like to block this number in %s? - Would you also like to block this number in %s? + + Would you also like to block this number in %s? + Would you also like to block these numbers in %s? + + + Would you also like to unblock this number in %s? + Would you also like to unblock these numbers in %s? + + Android Blocking Manager Call Control Automatically filter your calls and messages in one convenient place! Community IQ™ allows you to prevent unwanted messages from community known spammers @@ -267,8 +274,6 @@ Blocking Your blocked conversations will appear here - Unblock - Would you like to unblock this conversation? About Version @@ -332,13 +337,13 @@ Delete + Yes Cancel Delete Save Stop More Set - Unblock Undo Copied