Move blocked messages to their own screen

This commit is contained in:
moezbhatti
2019-08-29 00:14:02 +02:00
parent e163022f50
commit cdfd75fc01
13 changed files with 240 additions and 90 deletions
@@ -19,7 +19,6 @@
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
@@ -28,6 +27,7 @@ import com.moez.QKSMS.common.base.QkController
import com.moez.QKSMS.common.util.Colors
import com.moez.QKSMS.common.util.extensions.animateLayoutChanges
import com.moez.QKSMS.feature.blocking.manager.BlockingManagerController
import com.moez.QKSMS.feature.blocking.messages.BlockedMessagesController
import com.moez.QKSMS.injection.appComponent
import kotlinx.android.synthetic.main.blocking_controller.*
import kotlinx.android.synthetic.main.settings_switch_widget.view.*
@@ -36,10 +36,9 @@ import javax.inject.Inject
class BlockingController : QkController<BlockingView, BlockingState, BlockingPresenter>(), BlockingView {
override val blockingManagerIntent by lazy { blockingManager.clicks() }
override val blockedMessagesIntent by lazy { blockedNumbers.clicks() }
override val dropClickedIntent by lazy { drop.clicks() }
override val conversationClicks by lazy { blockingAdapter.clicks }
@Inject lateinit var blockingAdapter: BlockingAdapter
@Inject lateinit var colors: Colors
@Inject override lateinit var presenter: BlockingPresenter
@@ -51,10 +50,6 @@ class BlockingController : QkController<BlockingView, BlockingState, BlockingPre
override fun onViewCreated() {
super.onViewCreated()
blockingAdapter.emptyView = empty
conversations.adapter = blockingAdapter
parent.postDelayed({ parent?.animateLayoutChanges = true }, 100)
}
@@ -68,8 +63,12 @@ class BlockingController : QkController<BlockingView, BlockingState, BlockingPre
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 openBlockedMessages() {
router.pushController(RouterTransaction.with(BlockedMessagesController())
.pushChangeHandler(QkChangeHandler())
.popChangeHandler(QkChangeHandler()))
}
override fun openBlockingManager() {
@@ -20,10 +20,7 @@ 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.extensions.asObservable
import com.moez.QKSMS.repository.ConversationRepository
import com.moez.QKSMS.util.Preferences
import com.uber.autodispose.android.lifecycle.scope
import com.uber.autodispose.autoDisposable
@@ -32,15 +29,10 @@ import javax.inject.Inject
class BlockingPresenter @Inject constructor(
context: Context,
conversationRepo: ConversationRepository,
private val navigator: Navigator,
private val prefs: Preferences
) : QkPresenter<BlockingView, BlockingState>(BlockingState()) {
init {
val blockedConversations = conversationRepo.getBlockedConversations()
newState { copy(data = blockedConversations) }
disposables += prefs.blockingManager.asObservable()
.map { client ->
when (client) {
@@ -54,14 +46,6 @@ class BlockingPresenter @Inject constructor(
disposables += prefs.drop.asObservable()
.subscribe { enabled -> newState { copy(dropEnabled = enabled) } }
// Trigger a refresh if we go between having some/no blocked conversations, otherwise the header won't update
disposables += blockedConversations
.asObservable()
.filter { it.isValid && it.isLoaded }
.map { it.isEmpty() }
.distinctUntilChanged()
.subscribe { newState { copy() } }
}
override fun bindIntents(view: BlockingView) {
@@ -71,13 +55,13 @@ class BlockingPresenter @Inject constructor(
.autoDisposable(view.scope())
.subscribe { view.openBlockingManager() }
view.blockedMessagesIntent
.autoDisposable(view.scope())
.subscribe { view.openBlockedMessages() }
view.dropClickedIntent
.autoDisposable(view.scope())
.subscribe { prefs.drop.set(!prefs.drop.get()) }
view.conversationClicks
.autoDisposable(view.scope())
.subscribe { threadId -> navigator.showConversation(threadId) }
}
}
@@ -18,11 +18,7 @@
*/
package com.moez.QKSMS.feature.blocking
import com.moez.QKSMS.model.Conversation
import io.realm.RealmResults
data class BlockingState(
val blockingManager: String = "",
val dropEnabled: Boolean = false,
val data: RealmResults<Conversation>? = null
)
val dropEnabled: Boolean = false
)
@@ -24,8 +24,9 @@ import io.reactivex.Observable
interface BlockingView : QkViewContract<BlockingState> {
val blockingManagerIntent: Observable<*>
val blockedMessagesIntent: Observable<*>
val dropClickedIntent: Observable<*>
val conversationClicks: Observable<Long>
fun openBlockingManager()
fun openBlockedMessages()
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 Moez Bhatti <moez.bhatti@gmail.com>
* Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com>
*
* This file is part of QKSMS.
*
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.moez.QKSMS.feature.blocking
package com.moez.QKSMS.feature.blocking.messages
import android.view.LayoutInflater
import android.view.ViewGroup
@@ -28,7 +28,7 @@ import io.reactivex.subjects.PublishSubject
import kotlinx.android.synthetic.main.blocked_list_item.view.*
import javax.inject.Inject
class BlockingAdapter @Inject constructor() : QkRealmAdapter<Conversation>() {
class BlockedMessagesAdapter @Inject constructor() : QkRealmAdapter<Conversation>() {
val clicks: PublishSubject<Long> = PublishSubject.create()
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.moez.QKSMS.feature.blocking.messages
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.injection.appComponent
import kotlinx.android.synthetic.main.blocked_messages_controller.*
import javax.inject.Inject
class BlockedMessagesController : QkController<BlockedMessagesView, BlockedMessagesState, BlockedMessagesPresenter>(),
BlockedMessagesView {
override val conversationClicks by lazy { blockedMessagesAdapter.clicks }
@Inject lateinit var blockedMessagesAdapter: BlockedMessagesAdapter
@Inject lateinit var colors: Colors
@Inject override lateinit var presenter: BlockedMessagesPresenter
init {
appComponent.inject(this)
retainViewMode = RetainViewMode.RETAIN_DETACH
layoutRes = R.layout.blocked_messages_controller
}
override fun onViewCreated() {
super.onViewCreated()
blockedMessagesAdapter.emptyView = empty
conversations.adapter = blockedMessagesAdapter
}
override fun onAttach(view: View) {
super.onAttach(view)
presenter.bindIntents(this)
setTitle(R.string.blocked_messages_title)
showBackButton(true)
}
override fun render(state: BlockedMessagesState) {
blockedMessagesAdapter.updateData(state.data)
}
}
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.moez.QKSMS.feature.blocking.messages
import com.moez.QKSMS.common.Navigator
import com.moez.QKSMS.common.base.QkPresenter
import com.moez.QKSMS.repository.ConversationRepository
import com.uber.autodispose.android.lifecycle.scope
import com.uber.autodispose.autoDisposable
import javax.inject.Inject
class BlockedMessagesPresenter @Inject constructor(
conversationRepo: ConversationRepository,
private val navigator: Navigator
) : QkPresenter<BlockedMessagesView, BlockedMessagesState>(BlockedMessagesState(
data = conversationRepo.getBlockedConversations()
)) {
override fun bindIntents(view: BlockedMessagesView) {
super.bindIntents(view)
view.conversationClicks
.autoDisposable(view.scope())
.subscribe { threadId -> navigator.showConversation(threadId) }
}
}
@@ -0,0 +1,26 @@
/*
* Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.moez.QKSMS.feature.blocking.messages
import com.moez.QKSMS.model.Conversation
import io.realm.RealmResults
data class BlockedMessagesState(
val data: RealmResults<Conversation>? = null
)
@@ -0,0 +1,26 @@
/*
* Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.moez.QKSMS.feature.blocking.messages
import com.moez.QKSMS.common.base.QkViewContract
import io.reactivex.Observable
interface BlockedMessagesView : QkViewContract<BlockedMessagesState> {
val conversationClicks: Observable<Long>
}
@@ -31,6 +31,7 @@ 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.blocking.messages.BlockedMessagesController
import com.moez.QKSMS.feature.blocking.numbers.BlockedNumbersController
import com.moez.QKSMS.feature.compose.DetailedChipView
import com.moez.QKSMS.feature.conversationinfo.injection.ConversationInfoComponent
@@ -63,6 +64,7 @@ interface AppComponent {
fun inject(controller: AboutController)
fun inject(controller: BackupController)
fun inject(controller: BlockedMessagesController)
fun inject(controller: BlockedNumbersController)
fun inject(controller: BlockingController)
fun inject(controller: BlockingManagerController)
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2019 Moez Bhatti <moez.bhatti@gmail.com>
~
~ 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 <http://www.gnu.org/licenses/>.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/windowBackground">
<com.moez.QKSMS.common.widget.QkTextView
android:id="@+id/empty"
style="@style/TextSecondary"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:padding="56dp"
android:text="@string/blocked_messages_empty" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/conversations"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="8dp"
android:paddingBottom="8dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/blocked_list_item" />
</FrameLayout>
@@ -17,7 +17,7 @@
~ You should have received a copy of the GNU General Public License
~ along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
-->
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@@ -25,71 +25,35 @@
android:background="?android:attr/windowBackground"
android:clipToPadding="false">
<androidx.constraintlayout.widget.ConstraintLayout
<LinearLayout
android:id="@+id/parent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="16dp"
android:paddingBottom="16dp">
<com.moez.QKSMS.common.widget.PreferenceView
android:id="@+id/blockingManager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintTop_toTopOf="parent"
app:title="@string/blocking_manager_title"
tools:summary="@string/blocking_manager_qksms_title" />
<com.moez.QKSMS.common.widget.PreferenceView
android:id="@+id/blockedNumbers"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/blocked_messages_title" />
<com.moez.QKSMS.common.widget.PreferenceView
android:id="@+id/drop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/blockingManager"
app:summary="@string/blocking_drop_summary"
app:title="@string/blocking_drop_title"
app:widget="@layout/settings_switch_widget" />
<View
android:id="@+id/conversationsDivider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="16dp"
android:background="?android:attr/divider"
app:layout_constraintTop_toBottomOf="@+id/drop" />
</LinearLayout>
<com.moez.QKSMS.common.widget.QkTextView
android:id="@+id/blockedLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:text="@string/blocking_conversations"
android:textColor="?android:attr/textColorSecondary"
android:textStyle="bold"
app:layout_constraintTop_toBottomOf="@+id/conversationsDivider"
app:textSize="secondary" />
<com.moez.QKSMS.common.widget.QkTextView
android:id="@+id/empty"
style="@style/TextSecondary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="56dp"
android:text="@string/blocking_empty"
app:layout_constraintTop_toBottomOf="@+id/blockedLabel" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/conversations"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toBottomOf="@+id/blockedLabel"
tools:listitem="@layout/blocked_list_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</ScrollView>
+3 -1
View File
@@ -255,7 +255,6 @@
<string name="blocking_drop_title">Drop messages</string>
<string name="blocking_drop_summary">Drop incoming messages from blocked senders instead of hiding them</string>
<string name="blocking_conversations">Blocked conversations</string>
<string name="blocking_empty">Your blocked conversations will appear here</string>
<string name="blocking_manager_title">Blocking Manager</string>
<string name="blocking_manager_qksms_title">QKSMS</string>
@@ -274,6 +273,9 @@
<string name="blocked_numbers_dialog_hint">Phone number</string>
<string name="blocked_numbers_dialog_block">Block</string>
<string name="blocked_messages_title">Blocked messages</string>
<string name="blocked_messages_empty">Your blocked messages will appear here</string>
<string name="blocking_block_title">Block</string>
<string name="blocking_unblock_title">Unblock</string>
<plurals name="blocking_block_external">