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 bd0270ab..b7119841 100644 --- a/data/src/main/java/com/moez/QKSMS/blocking/ShouldIAnswerBlockingClient.kt +++ b/data/src/main/java/com/moez/QKSMS/blocking/ShouldIAnswerBlockingClient.kt @@ -28,7 +28,6 @@ import android.os.IBinder import android.os.Message import android.os.Messenger import androidx.core.os.bundleOf -import com.moez.QKSMS.util.Preferences import com.moez.QKSMS.util.tryOrNull import io.reactivex.Completable import io.reactivex.Single @@ -36,8 +35,7 @@ import io.reactivex.subjects.SingleSubject import javax.inject.Inject class ShouldIAnswerBlockingClient @Inject constructor( - private val context: Context, - private val prefs: Preferences + private val context: Context ) : BlockingClient { companion object { @@ -53,7 +51,7 @@ class ShouldIAnswerBlockingClient @Inject constructor( * Return a Single which emits whether or not the given [address] should be blocked */ override fun isBlocked(address: String): Single { - return Binder(context, prefs, address).isBlocked() + return Binder(context, address).isBlocked() } override fun block(addresses: List): Completable = Completable.fromCallable { showSia() } @@ -70,7 +68,6 @@ class ShouldIAnswerBlockingClient @Inject constructor( private class Binder( private val context: Context, - private val prefs: Preferences, private val address: String ) : ServiceConnection { @@ -79,22 +76,18 @@ class ShouldIAnswerBlockingClient @Inject constructor( private var isBound: Boolean = false fun isBlocked(): Single { - var intent: Intent? = null - // If either version of Should I Answer? is installed and SIA is enabled, build the // intent to request a rating - if (prefs.sia.get()) { - intent = tryOrNull(false) { - context.packageManager.getApplicationInfo("org.mistergroup.shouldianswer", 0).enabled - Intent("org.mistergroup.shouldianswer.PublicService").setPackage("org.mistergroup.shouldianswer") - } ?: tryOrNull(false) { - context.packageManager.getApplicationInfo("org.mistergroup.shouldianswerpersonal", 0).enabled - Intent("org.mistergroup.shouldianswerpersonal.PublicService") - .setPackage("org.mistergroup.shouldianswerpersonal") - } ?: tryOrNull(false) { - context.packageManager.getApplicationInfo("org.mistergroup.muzutozvednout", 0).enabled - Intent("org.mistergroup.muzutozvednout.PublicService").setPackage("org.mistergroup.muzutozvednout") - } + val intent: Intent? = tryOrNull(false) { + context.packageManager.getApplicationInfo("org.mistergroup.shouldianswer", 0).enabled + Intent("org.mistergroup.shouldianswer.PublicService").setPackage("org.mistergroup.shouldianswer") + } ?: tryOrNull(false) { + context.packageManager.getApplicationInfo("org.mistergroup.shouldianswerpersonal", 0).enabled + Intent("org.mistergroup.shouldianswerpersonal.PublicService") + .setPackage("org.mistergroup.shouldianswerpersonal") + } ?: tryOrNull(false) { + context.packageManager.getApplicationInfo("org.mistergroup.muzutozvednout", 0).enabled + Intent("org.mistergroup.muzutozvednout.PublicService").setPackage("org.mistergroup.muzutozvednout") } // If the intent isn't null, bind the service and wait for a result. Otherwise, don't block 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 27174846..6a7865f9 100644 --- a/domain/src/main/java/com/moez/QKSMS/util/Preferences.kt +++ b/domain/src/main/java/com/moez/QKSMS/util/Preferences.kt @@ -81,8 +81,6 @@ class Preferences @Inject constructor(private val rxPrefs: RxSharedPreferences) 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) val notifAction1 = rxPrefs.getInteger("notifAction1", NOTIFICATION_ACTION_READ) val notifAction2 = rxPrefs.getInteger("notifAction2", NOTIFICATION_ACTION_REPLY) diff --git a/presentation/src/main/java/com/moez/QKSMS/common/widget/PreferenceView.kt b/presentation/src/main/java/com/moez/QKSMS/common/widget/PreferenceView.kt index d905c66c..45fa352e 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/widget/PreferenceView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/widget/PreferenceView.kt @@ -32,7 +32,9 @@ import com.moez.QKSMS.common.util.extensions.setVisible import com.moez.QKSMS.injection.appComponent import kotlinx.android.synthetic.main.preference_view.view.* -class PreferenceView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : LinearLayoutCompat(context, attrs) { +class PreferenceView @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null +) : LinearLayoutCompat(context, attrs) { var title: String? = null set(value) { diff --git a/presentation/src/main/java/com/moez/QKSMS/common/widget/RadioPreferenceView.kt b/presentation/src/main/java/com/moez/QKSMS/common/widget/RadioPreferenceView.kt new file mode 100644 index 00000000..61d2ed28 --- /dev/null +++ b/presentation/src/main/java/com/moez/QKSMS/common/widget/RadioPreferenceView.kt @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2017 Moez Bhatti + * + * This file is part of QKSMS. + * + * QKSMS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QKSMS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QKSMS. If not, see . + */ +package com.moez.QKSMS.common.widget + +import android.content.Context +import android.content.res.ColorStateList +import android.util.AttributeSet +import android.view.View +import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import com.moez.QKSMS.R +import com.moez.QKSMS.common.util.Colors +import com.moez.QKSMS.common.util.extensions.resolveThemeAttribute +import com.moez.QKSMS.common.util.extensions.resolveThemeColor +import com.moez.QKSMS.common.util.extensions.setVisible +import com.moez.QKSMS.injection.appComponent +import kotlinx.android.synthetic.main.radio_preference_view.view.* +import javax.inject.Inject + +class RadioPreferenceView @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null +) : ConstraintLayout(context, attrs) { + + @Inject lateinit var colors: Colors + + var title: String? = null + set(value) { + field = value + + if (isInEditMode) { + findViewById(R.id.titleView).text = value + } else { + titleView.text = value + } + } + + var summary: String? = null + set(value) { + field = value + + + if (isInEditMode) { + findViewById(R.id.summaryView).run { + text = value + setVisible(value?.isNotEmpty() == true) + } + } else { + summaryView.text = value + summaryView.setVisible(value?.isNotEmpty() == true) + } + } + + init { + if (!isInEditMode) { + appComponent.inject(this) + } + + View.inflate(context, R.layout.radio_preference_view, this) + setBackgroundResource(context.resolveThemeAttribute(R.attr.selectableItemBackground)) + + val states = arrayOf( + intArrayOf(android.R.attr.state_checked), + intArrayOf(-android.R.attr.state_checked)) + + val themeColor = when (isInEditMode) { + true -> context.resources.getColor(R.color.tools_theme) + false -> colors.theme().theme + } + val textSecondary = context.resolveThemeColor(android.R.attr.textColorTertiary) + radioButton.buttonTintList = ColorStateList(states, intArrayOf(themeColor, textSecondary)) + + context.obtainStyledAttributes(attrs, R.styleable.RadioPreferenceView)?.run { + title = getString(R.styleable.RadioPreferenceView_title) + summary = getString(R.styleable.RadioPreferenceView_summary) + recycle() + } + } + +} \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingActivity.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingActivity.kt index 48694739..e028400f 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingActivity.kt @@ -19,46 +19,33 @@ package com.moez.QKSMS.feature.blocking import android.os.Bundle -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.ViewModelProviders -import com.jakewharton.rxbinding2.view.clicks +import com.bluelinelabs.conductor.Conductor +import com.bluelinelabs.conductor.Router +import com.bluelinelabs.conductor.RouterTransaction import com.moez.QKSMS.R import com.moez.QKSMS.common.base.QkThemedActivity import dagger.android.AndroidInjection -import kotlinx.android.synthetic.main.blocking_activity.* -import kotlinx.android.synthetic.main.settings_switch_widget.view.* -import javax.inject.Inject +import kotlinx.android.synthetic.main.container_activity.* -class BlockingActivity : QkThemedActivity(), BlockingView { +class BlockingActivity : QkThemedActivity() { - @Inject lateinit var blockingAdapter: BlockingAdapter - @Inject lateinit var viewModelFactory: ViewModelProvider.Factory - - override val ccClickedIntent by lazy { callControl.clicks() } - override val siaClickedIntent by lazy { shouldIAnswer.clicks() } - override val dropClickedIntent by lazy { drop.clicks() } - override val conversationClicks by lazy { blockingAdapter.clicks } - - private val viewModel by lazy { ViewModelProviders.of(this, viewModelFactory)[BlockingViewModel::class.java] } + private lateinit var router: Router override fun onCreate(savedInstanceState: Bundle?) { AndroidInjection.inject(this) super.onCreate(savedInstanceState) - setContentView(R.layout.blocking_activity) - setTitle(R.string.blocking_title) - showBackButton(true) - viewModel.bindView(this) + setContentView(R.layout.container_activity) - blockingAdapter.emptyView = empty - conversations.adapter = blockingAdapter + router = Conductor.attachRouter(this, container, savedInstanceState) + if (!router.hasRootController()) { + router.setRoot(RouterTransaction.with(BlockingController())) + } } - override fun render(state: BlockingState) { - callControl.checkbox.isChecked = state.ccEnabled - shouldIAnswer.checkbox.isChecked = state.siaEnabled - drop.checkbox.isChecked = state.dropEnabled - - blockingAdapter.updateData(state.data) + override fun onBackPressed() { + if (!router.handleBack()) { + super.onBackPressed() + } } } \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingActivityModule.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingActivityModule.kt deleted file mode 100644 index 8aed11cf..00000000 --- a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingActivityModule.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2017 Moez Bhatti - * - * This file is part of QKSMS. - * - * QKSMS is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * QKSMS is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with QKSMS. If not, see . - */ -package com.moez.QKSMS.feature.blocking - -import androidx.lifecycle.ViewModel -import com.moez.QKSMS.injection.ViewModelKey -import dagger.Module -import dagger.Provides -import dagger.multibindings.IntoMap - -@Module -class BlockingActivityModule { - - @Provides - @IntoMap - @ViewModelKey(BlockingViewModel::class) - fun provideBlockingViewModel(viewModel: BlockingViewModel): ViewModel = viewModel - -} \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingController.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingController.kt new file mode 100644 index 00000000..bd2c2eab --- /dev/null +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingController.kt @@ -0,0 +1,58 @@ +package com.moez.QKSMS.feature.blocking + +import android.view.View +import androidx.core.view.isVisible +import com.bluelinelabs.conductor.RouterTransaction +import com.jakewharton.rxbinding2.view.clicks +import com.moez.QKSMS.R +import com.moez.QKSMS.common.QkChangeHandler +import com.moez.QKSMS.common.base.QkController +import com.moez.QKSMS.feature.blocking.manager.BlockingManagerController +import com.moez.QKSMS.injection.appComponent +import kotlinx.android.synthetic.main.blocking_controller.* +import kotlinx.android.synthetic.main.settings_switch_widget.view.* +import javax.inject.Inject + +class BlockingController : QkController(), BlockingView { + + override val blockingManagerIntent by lazy { blockingManager.clicks() } + override val dropClickedIntent by lazy { drop.clicks() } + override val conversationClicks by lazy { blockingAdapter.clicks } + + @Inject lateinit var blockingAdapter: BlockingAdapter + @Inject override lateinit var presenter: BlockingPresenter + + init { + appComponent.inject(this) + retainViewMode = RetainViewMode.RETAIN_DETACH + layoutRes = R.layout.blocking_controller + } + + override fun onViewCreated() { + super.onViewCreated() + + blockingAdapter.emptyView = empty + conversations.adapter = blockingAdapter + } + + override fun onAttach(view: View) { + super.onAttach(view) + presenter.bindIntents(this) + setTitle(R.string.blocking_title) + showBackButton(true) + } + + override fun render(state: BlockingState) { + blockingManager.summary = state.blockingManager + drop.checkbox.isChecked = state.dropEnabled + blockedLabel.isVisible = state.data?.isNotEmpty() == true + blockingAdapter.updateData(state.data) + } + + override fun openBlockingManager() { + router.pushController(RouterTransaction.with(BlockingManagerController()) + .pushChangeHandler(QkChangeHandler()) + .popChangeHandler(QkChangeHandler())) + } + +} diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingPresenter.kt new file mode 100644 index 00000000..69616096 --- /dev/null +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingPresenter.kt @@ -0,0 +1,54 @@ +package com.moez.QKSMS.feature.blocking + +import android.content.Context +import com.moez.QKSMS.R +import com.moez.QKSMS.common.Navigator +import com.moez.QKSMS.common.base.QkPresenter +import com.moez.QKSMS.repository.ConversationRepository +import com.moez.QKSMS.util.Preferences +import com.uber.autodispose.kotlin.autoDisposable +import io.reactivex.rxkotlin.plusAssign +import javax.inject.Inject + +class BlockingPresenter @Inject constructor( + private val context: Context, + private val conversationRepo: ConversationRepository, + private val navigator: Navigator, + private val prefs: Preferences +) : QkPresenter(BlockingState()) { + + init { + newState { copy(data = conversationRepo.getBlockedConversations()) } + + disposables += prefs.blockingManager.asObservable() + .map { client -> + when (client) { + Preferences.BLOCKING_MANAGER_SIA -> R.string.blocking_manager_sia_title + Preferences.BLOCKING_MANAGER_CC -> R.string.blocking_manager_call_control_title + else -> R.string.app_name + } + } + .map(context::getString) + .subscribe { manager -> newState { copy(blockingManager = manager) }} + + disposables += prefs.drop.asObservable() + .subscribe { enabled -> newState { copy(dropEnabled = enabled) } } + } + + override fun bindIntents(view: BlockingView) { + super.bindIntents(view) + + view.blockingManagerIntent + .autoDisposable(view.scope()) + .subscribe { view.openBlockingManager() } + + view.dropClickedIntent + .autoDisposable(view.scope()) + .subscribe { prefs.drop.set(!prefs.drop.get()) } + + view.conversationClicks + .autoDisposable(view.scope()) + .subscribe { threadId -> navigator.showConversation(threadId) } + } + +} diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingState.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingState.kt index 5b4b8778..c7f6b9c6 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingState.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingState.kt @@ -22,8 +22,7 @@ import com.moez.QKSMS.model.Conversation import io.realm.RealmResults data class BlockingState( - val ccEnabled: Boolean = false, - val siaEnabled: Boolean = false, + val blockingManager: String = "", val dropEnabled: Boolean = false, val data: RealmResults? = null ) \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingView.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingView.kt index 0d53005a..9af28686 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingView.kt @@ -18,14 +18,14 @@ */ package com.moez.QKSMS.feature.blocking -import com.moez.QKSMS.common.base.QkView +import com.moez.QKSMS.common.base.QkViewContract import io.reactivex.Observable -interface BlockingView : QkView { +interface BlockingView : QkViewContract { - val ccClickedIntent: Observable<*> - val siaClickedIntent: Observable<*> + val blockingManagerIntent: Observable<*> val dropClickedIntent: Observable<*> val conversationClicks: Observable + fun openBlockingManager() } diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingViewModel.kt deleted file mode 100644 index d80d09aa..00000000 --- a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/BlockingViewModel.kt +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2017 Moez Bhatti - * - * This file is part of QKSMS. - * - * QKSMS is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * QKSMS is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with QKSMS. If not, see . - */ -package com.moez.QKSMS.feature.blocking - -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.manager.AnalyticsManager -import com.moez.QKSMS.repository.ConversationRepository -import com.moez.QKSMS.util.Preferences -import com.uber.autodispose.android.lifecycle.scope -import com.uber.autodispose.autoDisposable -import io.reactivex.rxkotlin.plusAssign -import javax.inject.Inject - -class BlockingViewModel @Inject constructor( - private val context: Context, - private val analytics: AnalyticsManager, - private val conversationRepo: ConversationRepository, - private val navigator: Navigator, - private val prefs: Preferences -) : QkViewModel(BlockingState()) { - - init { - newState { copy(data = conversationRepo.getBlockedConversations()) } - - disposables += prefs.callControl.asObservable() - .subscribe { enabled -> newState { copy(ccEnabled = enabled) } } - - disposables += prefs.sia.asObservable() - .subscribe { enabled -> newState { copy(siaEnabled = enabled) } } - - disposables += prefs.drop.asObservable() - .subscribe { enabled -> newState { copy(dropEnabled = enabled) } } - } - - override fun bindView(view: BlockingView) { - super.bindView(view) - - view.ccClickedIntent - .map { context.isInstalled("com.flexaspect.android.everycallcontrol") } - .map { installed -> - if (!installed) { - navigator.showCallControl() - } - - val enabled = prefs.callControl.get() - analytics.track("Clicked Call Control", Pair("enable", !enabled), Pair("installed", installed)) - installed && !enabled - } - .autoDisposable(view.scope()) - .subscribe(prefs.callControl::set) - - view.siaClickedIntent - .map { - listOf("org.mistergroup.shouldianswer", - "org.mistergroup.shouldianswerpersonal", - "org.mistergroup.muzutozvednout") - .any(context::isInstalled) - } - .map { installed -> - if (!installed) { - navigator.showSia() - } - - val enabled = prefs.sia.get() - analytics.track("Clicked SIA", Pair("enable", !enabled), Pair("installed", installed)) - installed && !enabled - } - .autoDisposable(view.scope()) - .subscribe(prefs.sia::set) - - view.dropClickedIntent - .autoDisposable(view.scope()) - .subscribe { prefs.drop.set(!prefs.drop.get()) } - - view.conversationClicks - .autoDisposable(view.scope()) - .subscribe { threadId -> navigator.showConversation(threadId) } - } - -} diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerController.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerController.kt new file mode 100644 index 00000000..3647d7c7 --- /dev/null +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerController.kt @@ -0,0 +1,42 @@ +package com.moez.QKSMS.feature.blocking.manager + +import android.view.View +import com.jakewharton.rxbinding2.view.clicks +import com.moez.QKSMS.R +import com.moez.QKSMS.common.base.QkController +import com.moez.QKSMS.injection.appComponent +import com.moez.QKSMS.util.Preferences +import io.reactivex.Observable +import kotlinx.android.synthetic.main.blocking_manager_controller.* +import kotlinx.android.synthetic.main.radio_preference_view.view.* +import javax.inject.Inject + +class BlockingManagerController : QkController(), + BlockingManagerView { + + @Inject override lateinit var presenter: BlockingManagerPresenter + + init { + appComponent.inject(this) + retainViewMode = RetainViewMode.RETAIN_DETACH + layoutRes = R.layout.blocking_manager_controller + } + + override fun onAttach(view: View) { + super.onAttach(view) + presenter.bindIntents(this) + setTitle(R.string.blocking_manager_title) + showBackButton(true) + } + + override fun render(state: BlockingManagerState) { + qksms.radioButton.isChecked = state.blockingManager == Preferences.BLOCKING_MANAGER_QKSMS + callControl.radioButton.isChecked = state.blockingManager == Preferences.BLOCKING_MANAGER_CC + shouldIAnswer.radioButton.isChecked = state.blockingManager == Preferences.BLOCKING_MANAGER_SIA + } + + override fun qksmsClicked(): Observable<*> = qksms.clicks() + override fun callControlClicked(): Observable<*> = callControl.clicks() + override fun siaClicked(): Observable<*> = shouldIAnswer.clicks() + +} diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerPresenter.kt new file mode 100644 index 00000000..10a1edc5 --- /dev/null +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerPresenter.kt @@ -0,0 +1,65 @@ +package com.moez.QKSMS.feature.blocking.manager + +import android.content.Context +import com.moez.QKSMS.common.Navigator +import com.moez.QKSMS.common.base.QkPresenter +import com.moez.QKSMS.common.util.extensions.isInstalled +import com.moez.QKSMS.manager.AnalyticsManager +import com.moez.QKSMS.util.Preferences +import com.uber.autodispose.kotlin.autoDisposable +import io.reactivex.rxkotlin.plusAssign +import javax.inject.Inject + +class BlockingManagerPresenter @Inject constructor( + private val analytics: AnalyticsManager, + private val context: Context, + private val navigator: Navigator, + private val prefs: Preferences +) : QkPresenter(BlockingManagerState()) { + + init { + disposables += prefs.blockingManager.asObservable() + .subscribe { manager -> newState { copy(blockingManager = manager) } } + } + + override fun bindIntents(view: BlockingManagerView) { + super.bindIntents(view) + + view.qksmsClicked() + .autoDisposable(view.scope()) + .subscribe { prefs.blockingManager.set(Preferences.BLOCKING_MANAGER_QKSMS) } + + view.callControlClicked() + .filter { + val installed = context.isInstalled("com.flexaspect.android.everycallcontrol") + if (!installed) { + navigator.showCallControl() + } + + val enabled = prefs.blockingManager.get() == Preferences.BLOCKING_MANAGER_CC + analytics.track("Clicked Call Control", Pair("enable", !enabled), Pair("installed", installed)) + installed + } + .autoDisposable(view.scope()) + .subscribe { prefs.blockingManager.set(Preferences.BLOCKING_MANAGER_CC) } + + view.siaClicked() + .filter { + val installed = listOf("org.mistergroup.shouldianswer", + "org.mistergroup.shouldianswerpersonal", + "org.mistergroup.muzutozvednout") + .any(context::isInstalled) + + if (!installed) { + navigator.showSia() + } + + val enabled = prefs.blockingManager.get() == Preferences.BLOCKING_MANAGER_SIA + analytics.track("Clicked SIA", Pair("enable", !enabled), Pair("installed", installed)) + installed && !enabled + } + .autoDisposable(view.scope()) + .subscribe { prefs.blockingManager.set(Preferences.BLOCKING_MANAGER_SIA) } + } + +} diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerState.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerState.kt new file mode 100644 index 00000000..f1719f91 --- /dev/null +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerState.kt @@ -0,0 +1,5 @@ +package com.moez.QKSMS.feature.blocking.manager + +data class BlockingManagerState( + val blockingManager: Int = 0 +) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerView.kt b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerView.kt new file mode 100644 index 00000000..956bacab --- /dev/null +++ b/presentation/src/main/java/com/moez/QKSMS/feature/blocking/manager/BlockingManagerView.kt @@ -0,0 +1,12 @@ +package com.moez.QKSMS.feature.blocking.manager + +import com.moez.QKSMS.common.base.QkViewContract +import io.reactivex.Observable + +interface BlockingManagerView : QkViewContract { + + fun qksmsClicked(): Observable<*> + fun callControlClicked(): Observable<*> + fun siaClicked(): Observable<*> + +} diff --git a/presentation/src/main/java/com/moez/QKSMS/injection/AppComponent.kt b/presentation/src/main/java/com/moez/QKSMS/injection/AppComponent.kt index e91d5ed7..0c35f5c0 100644 --- a/presentation/src/main/java/com/moez/QKSMS/injection/AppComponent.kt +++ b/presentation/src/main/java/com/moez/QKSMS/injection/AppComponent.kt @@ -27,7 +27,10 @@ import com.moez.QKSMS.common.widget.PreferenceView import com.moez.QKSMS.common.widget.QkEditText import com.moez.QKSMS.common.widget.QkSwitch import com.moez.QKSMS.common.widget.QkTextView +import com.moez.QKSMS.common.widget.RadioPreferenceView import com.moez.QKSMS.feature.backup.BackupController +import com.moez.QKSMS.feature.blocking.BlockingController +import com.moez.QKSMS.feature.blocking.manager.BlockingManagerController import com.moez.QKSMS.feature.compose.DetailedChipView import com.moez.QKSMS.feature.conversationinfo.injection.ConversationInfoComponent import com.moez.QKSMS.feature.settings.SettingsController @@ -59,6 +62,8 @@ interface AppComponent { fun inject(controller: AboutController) fun inject(controller: BackupController) + fun inject(controller: BlockingController) + fun inject(controller: BlockingManagerController) fun inject(controller: SettingsController) fun inject(controller: SwipeActionsController) @@ -77,6 +82,7 @@ interface AppComponent { fun inject(view: DetailedChipView) fun inject(view: PagerTitleView) fun inject(view: PreferenceView) + fun inject(view: RadioPreferenceView) fun inject(view: QkEditText) fun inject(view: QkSwitch) fun inject(view: QkTextView) diff --git a/presentation/src/main/java/com/moez/QKSMS/injection/android/ActivityBuilderModule.kt b/presentation/src/main/java/com/moez/QKSMS/injection/android/ActivityBuilderModule.kt index b5d379ba..44deebee 100644 --- a/presentation/src/main/java/com/moez/QKSMS/injection/android/ActivityBuilderModule.kt +++ b/presentation/src/main/java/com/moez/QKSMS/injection/android/ActivityBuilderModule.kt @@ -20,7 +20,6 @@ package com.moez.QKSMS.injection.android import com.moez.QKSMS.feature.backup.BackupActivity import com.moez.QKSMS.feature.blocking.BlockingActivity -import com.moez.QKSMS.feature.blocking.BlockingActivityModule import com.moez.QKSMS.feature.compose.ComposeActivity import com.moez.QKSMS.feature.compose.ComposeActivityModule import com.moez.QKSMS.feature.conversationinfo.ConversationInfoActivity @@ -85,7 +84,7 @@ abstract class ActivityBuilderModule { abstract fun bindSettingsActivity(): SettingsActivity @ActivityScope - @ContributesAndroidInjector(modules = [BlockingActivityModule::class]) + @ContributesAndroidInjector(modules = []) abstract fun bindBlockingActivity(): BlockingActivity -} \ No newline at end of file +} diff --git a/presentation/src/main/res/layout/blocking_activity.xml b/presentation/src/main/res/layout/blocking_controller.xml similarity index 56% rename from presentation/src/main/res/layout/blocking_activity.xml rename to presentation/src/main/res/layout/blocking_controller.xml index 52472563..a0540da3 100644 --- a/presentation/src/main/res/layout/blocking_activity.xml +++ b/presentation/src/main/res/layout/blocking_controller.xml @@ -17,37 +17,28 @@ ~ You should have received a copy of the GNU General Public License ~ along with QKSMS. If not, see . --> - - - + android:layout_height="match_parent" + android:animateLayoutChanges="true" + android:background="?android:attr/windowBackground"> + android:text="@string/blocking_empty" /> + android:layout_height="match_parent" + android:paddingTop="8dp" + android:paddingBottom="8dp"> - - + app:title="@string/blocking_manager_title" + tools:summary="@string/app_name" /> + + - - - - - \ No newline at end of file + diff --git a/presentation/src/main/res/layout/blocking_manager_controller.xml b/presentation/src/main/res/layout/blocking_manager_controller.xml new file mode 100644 index 00000000..9dc54414 --- /dev/null +++ b/presentation/src/main/res/layout/blocking_manager_controller.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + diff --git a/presentation/src/main/res/layout/preference_view.xml b/presentation/src/main/res/layout/preference_view.xml index 26d199ec..09bef000 100644 --- a/presentation/src/main/res/layout/preference_view.xml +++ b/presentation/src/main/res/layout/preference_view.xml @@ -22,6 +22,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/selectableItemBackground" + android:gravity="center_vertical" + android:orientation="horizontal" tools:parentTag="com.moez.QKSMS.common.widget.PreferenceView"> + + + + + + + + + + diff --git a/presentation/src/main/res/values/attrs.xml b/presentation/src/main/res/values/attrs.xml index 04c4f5e0..d308658b 100644 --- a/presentation/src/main/res/values/attrs.xml +++ b/presentation/src/main/res/values/attrs.xml @@ -19,6 +19,9 @@ --> + + + @@ -45,11 +48,15 @@ - - - + + + + + + + \ No newline at end of file