Move all notification related prefs to separate activity for all API versions

This commit is contained in:
Moez Bhatti
2018-04-18 23:32:12 -04:00
parent 8cb733c013
commit 0027dfd8e0
12 changed files with 173 additions and 136 deletions
@@ -178,6 +178,12 @@ class Navigator @Inject constructor(private val context: Context, private val no
}
fun showNotificationSettings(threadId: Long = 0) {
val intent = Intent(context, NotificationPrefsActivity::class.java)
intent.putExtra("threadId", threadId)
startActivity(intent)
}
fun showNotificationChannel(threadId: Long = 0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (threadId != 0L) {
notificationManager.createNotificationChannel(threadId)
@@ -188,10 +194,6 @@ class Navigator @Inject constructor(private val context: Context, private val no
intent.putExtra(Settings.EXTRA_CHANNEL_ID, channelId)
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
startActivity(intent)
} else {
val intent = Intent(context, NotificationPrefsActivity::class.java)
intent.putExtra("threadId", threadId)
startActivity(intent)
}
}
@@ -19,16 +19,22 @@
package feature.notificationprefs
import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
import android.media.RingtoneManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import com.jakewharton.rxbinding2.view.clicks
import com.moez.QKSMS.R
import com.uber.autodispose.android.lifecycle.scope
import com.uber.autodispose.kotlin.autoDisposable
import common.MenuItemAdapter
import common.base.QkThemedActivity
import common.util.extensions.dpToPx
import common.util.extensions.setVisible
import common.widget.PreferenceView
import injection.appComponent
import io.reactivex.subjects.PublishSubject
@@ -39,11 +45,11 @@ import javax.inject.Inject
class NotificationPrefsActivity : QkThemedActivity<NotificationPrefsViewModel>(), NotificationPrefsView {
@Inject lateinit var nightModeAdapter: MenuItemAdapter
@Inject lateinit var mmsSizeAdapter: MenuItemAdapter
@Inject lateinit var notificationPreviewModeAdapter: MenuItemAdapter
override val viewModelClass = NotificationPrefsViewModel::class
override val preferenceClickIntent: Subject<PreferenceView> = PublishSubject.create()
override val notificationPreviewModeSelectedIntent by lazy { notificationPreviewModeAdapter.menuItemClicks }
override val ringtoneSelectedIntent: Subject<String> = PublishSubject.create()
init {
@@ -57,8 +63,14 @@ class NotificationPrefsActivity : QkThemedActivity<NotificationPrefsViewModel>()
showBackButton(true)
viewModel.bindView(this)
nightModeAdapter.setData(R.array.night_modes)
mmsSizeAdapter.setData(R.array.mms_sizes, R.array.mms_sizes_ids)
val hasOreo = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
notificationsO.setVisible(hasOreo)
notifications.setVisible(!hasOreo)
vibration.setVisible(!hasOreo)
ringtone.setVisible(!hasOreo)
notificationPreviewModeAdapter.setData(R.array.notification_preview_options)
colors.background
.autoDisposable(scope())
@@ -81,8 +93,28 @@ class NotificationPrefsActivity : QkThemedActivity<NotificationPrefsViewModel>()
}
notifications.checkbox.isChecked = state.notificationsEnabled
notificationPreviews.summary = state.notificationPreviewSummary
vibration.checkbox.isChecked = state.vibrationEnabled
ringtone.summary = state.ringtoneName
qkreply.checkbox.isChecked = state.qkReplyEnabled
qkreplyTapDismiss.setVisible(state.qkReplyEnabled)
qkreplyTapDismiss.checkbox.isChecked = state.qkReplyTapDismiss
}
override fun showNotificationPreviewModeDialog() {
val recyclerView = RecyclerView(this)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = notificationPreviewModeAdapter
recyclerView.setPadding(0, 8.dpToPx(this), 0, 8.dpToPx(this))
val dialog = AlertDialog.Builder(this)
.setView(recyclerView)
.create()
.apply { show() }
notificationPreviewModeAdapter.menuItemClicks
.autoDisposable(scope())
.subscribe { dialog.dismiss() }
}
override fun showRingtonePicker(default: Uri) {
@@ -18,9 +18,13 @@
*/
package feature.notificationprefs
import android.os.Build
data class NotificationPrefsState(
val conversationTitle: String = "",
val notificationsEnabled: Boolean = true,
val notificationPreviewSummary: String = "",
val vibrationEnabled: Boolean = true,
val ringtoneName: String = ""
)
val ringtoneName: String = "",
val qkReplyEnabled: Boolean = Build.VERSION.SDK_INT < Build.VERSION_CODES.N,
val qkReplyTapDismiss: Boolean = true)
@@ -19,15 +19,17 @@
package feature.notificationprefs
import android.net.Uri
import io.reactivex.Observable
import io.reactivex.subjects.Subject
import common.base.QkView
import common.widget.PreferenceView
import io.reactivex.Observable
import io.reactivex.subjects.Subject
interface NotificationPrefsView : QkView<NotificationPrefsState> {
val preferenceClickIntent: Subject<PreferenceView>
val notificationPreviewModeSelectedIntent: Subject<Int>
val ringtoneSelectedIntent: Observable<String>
fun showNotificationPreviewModeDialog()
fun showRingtonePicker(default: Uri)
}
@@ -27,15 +27,14 @@ import com.f2prateek.rx.preferences2.Preference
import com.moez.QKSMS.R
import com.uber.autodispose.android.lifecycle.scope
import com.uber.autodispose.kotlin.autoDisposable
import common.Navigator
import common.base.QkViewModel
import injection.appComponent
import util.Preferences
import io.reactivex.Flowable
import io.reactivex.rxkotlin.plusAssign
import io.reactivex.schedulers.Schedulers
import common.Navigator
import common.base.QkViewModel
import repository.MessageRepository
import timber.log.Timber
import util.Preferences
import util.extensions.mapNotNull
import javax.inject.Inject
@@ -68,6 +67,10 @@ class NotificationPrefsViewModel(intent: Intent) : QkViewModel<NotificationPrefs
disposables += notifications.asObservable()
.subscribe { enabled -> newState { it.copy(notificationsEnabled = enabled) } }
val notificationPreviewLabels = context.resources.getStringArray(R.array.notification_preview_options)
disposables += prefs.notificationPreviews().asObservable()
.subscribe { nightMode -> newState { it.copy(notificationPreviewSummary = notificationPreviewLabels[nightMode]) } }
disposables += vibration.asObservable()
.subscribe { enabled -> newState { it.copy(vibrationEnabled = enabled) } }
@@ -75,6 +78,12 @@ class NotificationPrefsViewModel(intent: Intent) : QkViewModel<NotificationPrefs
.map { uri -> uri.toUri() }
.map { uri -> RingtoneManager.getRingtone(context, uri).getTitle(context) }
.subscribe { title -> newState { it.copy(ringtoneName = title) } }
disposables += prefs.qkreply.asObservable()
.subscribe { enabled -> newState { it.copy(qkReplyEnabled = enabled) } }
disposables += prefs.qkreplyTapDismiss.asObservable()
.subscribe { enabled -> newState { it.copy(qkReplyTapDismiss = enabled) } }
}
override fun bindView(view: NotificationPrefsView) {
@@ -83,17 +92,27 @@ class NotificationPrefsViewModel(intent: Intent) : QkViewModel<NotificationPrefs
view.preferenceClickIntent
.autoDisposable(view.scope())
.subscribe {
Timber.v("Preference click: ${context.resources.getResourceName(it.id)}")
when (it.id) {
R.id.notificationsO -> navigator.showNotificationChannel(threadId)
R.id.notifications -> notifications.set(!notifications.get())
R.id.notificationPreviews -> view.showNotificationPreviewModeDialog()
R.id.vibration -> vibration.set(!vibration.get())
R.id.ringtone -> view.showRingtonePicker(Uri.parse(ringtone.get()))
R.id.qkreply -> prefs.qkreply.set(!prefs.qkreply.get())
R.id.qkreplyTapDismiss -> prefs.qkreplyTapDismiss.set(!prefs.qkreplyTapDismiss.get())
}
}
view.notificationPreviewModeSelectedIntent
.autoDisposable(view.scope())
.subscribe { prefs.notificationPreviews().set(it) }
view.ringtoneSelectedIntent
.autoDisposable(view.scope())
.subscribe { ringtone -> this.ringtone.set(ringtone) }
@@ -49,7 +49,6 @@ class SettingsActivity : QkThemedActivity<SettingsViewModel>(), SettingsView {
@Inject lateinit var nightModeAdapter: MenuItemAdapter
@Inject lateinit var textSizeAdapter: MenuItemAdapter
@Inject lateinit var notificationPreviewModeAdapter: MenuItemAdapter
@Inject lateinit var mmsSizeAdapter: MenuItemAdapter
override val viewModelClass = SettingsViewModel::class
@@ -59,7 +58,6 @@ class SettingsActivity : QkThemedActivity<SettingsViewModel>(), SettingsView {
override val startTimeSelectedIntent: Subject<Pair<Int, Int>> = PublishSubject.create()
override val endTimeSelectedIntent: Subject<Pair<Int, Int>> = PublishSubject.create()
override val textSizeSelectedIntent by lazy { textSizeAdapter.menuItemClicks }
override val notificationPreviewModeSelectedIntent by lazy { notificationPreviewModeAdapter.menuItemClicks }
override val mmsSizeSelectedIntent: Subject<Int> by lazy { mmsSizeAdapter.menuItemClicks }
// TODO remove this
@@ -88,7 +86,6 @@ class SettingsActivity : QkThemedActivity<SettingsViewModel>(), SettingsView {
nightModeAdapter.setData(R.array.night_modes)
textSizeAdapter.setData(R.array.text_sizes)
notificationPreviewModeAdapter.setData(R.array.notification_preview_options)
mmsSizeAdapter.setData(R.array.mms_sizes, R.array.mms_sizes_ids)
version.text = getString(R.string.settings_version, BuildConfig.VERSION_NAME)
@@ -127,12 +124,8 @@ class SettingsActivity : QkThemedActivity<SettingsViewModel>(), SettingsView {
black.setVisible(state.nightModeId != Preferences.NIGHT_MODE_OFF)
black.checkbox.isChecked = state.black
notificationPreviews.summary = state.notificationPreviewSummary
autoEmoji.checkbox.isChecked = state.autoEmojiEnabled
delivery.checkbox.isChecked = state.deliveryEnabled
qkreply.checkbox.isChecked = state.qkReplyEnabled
qkreplyTapDismiss.setVisible(state.qkReplyEnabled)
qkreplyTapDismiss.checkbox.isChecked = state.qkReplyTapDismiss
textSize.summary = state.textSizeSummary
systemFont.checkbox.isChecked = state.systemFontEnabled
@@ -195,22 +188,6 @@ class SettingsActivity : QkThemedActivity<SettingsViewModel>(), SettingsView {
textSizeDialog = null
}
override fun showNotificationPreviewModeDialog() {
val recyclerView = RecyclerView(this)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = notificationPreviewModeAdapter
recyclerView.setPadding(0, 8.dpToPx(this), 0, 8.dpToPx(this))
val dialog = AlertDialog.Builder(this)
.setView(recyclerView)
.create()
.apply { show() }
notificationPreviewModeAdapter.menuItemClicks
.autoDisposable(scope())
.subscribe { dialog.dismiss() }
}
override fun showMmsSizePicker() {
val recyclerView = RecyclerView(this)
recyclerView.layoutManager = LinearLayoutManager(this)
@@ -18,12 +18,10 @@
*/
package feature.settings
import android.os.Build
import util.Preferences
data class SettingsState(
val syncing: Boolean = false,
val isDefaultSmsApp: Boolean = false,
val theme: Int = 0,
val nightModeSummary: String = "",
@@ -33,10 +31,7 @@ data class SettingsState(
val black: Boolean = false,
val autoEmojiEnabled: Boolean = true,
val notificationsEnabled: Boolean = true,
val notificationPreviewSummary: String = "",
val deliveryEnabled: Boolean = false,
val qkReplyEnabled: Boolean = Build.VERSION.SDK_INT < Build.VERSION_CODES.N,
val qkReplyTapDismiss: Boolean = true,
val textSizeSummary: String = "",
val systemFontEnabled: Boolean = false,
val splitSmsEnabled: Boolean = false,
@@ -31,7 +31,6 @@ interface SettingsView : QkView<SettingsState> {
val startTimeSelectedIntent: Subject<Pair<Int, Int>>
val endTimeSelectedIntent: Subject<Pair<Int, Int>>
val textSizeSelectedIntent: Subject<Int>
val notificationPreviewModeSelectedIntent: Subject<Int>
val mmsSizeSelectedIntent: Observable<Int>
fun showNightModeDialog()
@@ -40,7 +39,6 @@ interface SettingsView : QkView<SettingsState> {
fun showStartTimePicker(hour: Int, minute: Int)
fun showEndTimePicker(hour: Int, minute: Int)
fun showTextSizePicker()
fun showNotificationPreviewModeDialog()
fun dismissTextSizePicker()
fun showMmsSizePicker()
fun dismissMmsSizePicker()
@@ -81,19 +81,9 @@ class SettingsViewModel : QkViewModel<SettingsView, SettingsState>(SettingsState
disposables += prefs.notifications().asObservable()
.subscribe { enabled -> newState { it.copy(notificationsEnabled = enabled) } }
val notificationPreviewLabels = context.resources.getStringArray(R.array.notification_preview_options)
disposables += prefs.notificationPreviews().asObservable()
.subscribe { nightMode -> newState { it.copy(notificationPreviewSummary = notificationPreviewLabels[nightMode]) } }
disposables += prefs.delivery.asObservable()
.subscribe { enabled -> newState { it.copy(deliveryEnabled = enabled) } }
disposables += prefs.qkreply.asObservable()
.subscribe { enabled -> newState { it.copy(qkReplyEnabled = enabled) } }
disposables += prefs.qkreplyTapDismiss.asObservable()
.subscribe { enabled -> newState { it.copy(qkReplyTapDismiss = enabled) } }
val textSizeLabels = context.resources.getStringArray(R.array.text_sizes)
disposables += prefs.textSize.asObservable()
.subscribe { textSize -> newState { it.copy(textSizeSummary = textSizeLabels[textSize]) } }
@@ -146,16 +136,10 @@ class SettingsViewModel : QkViewModel<SettingsView, SettingsState>(SettingsState
R.id.notifications -> navigator.showNotificationSettings()
R.id.notificationPreviews -> view.showNotificationPreviewModeDialog()
R.id.blocked -> navigator.showBlockedConversations()
R.id.delivery -> prefs.delivery.set(!prefs.delivery.get())
R.id.qkreply -> prefs.qkreply.set(!prefs.qkreply.get())
R.id.qkreplyTapDismiss -> prefs.qkreplyTapDismiss.set(!prefs.qkreplyTapDismiss.get())
R.id.textSize -> view.showTextSizePicker()
R.id.systemFont -> prefs.systemFont.set(!prefs.systemFont.get())
@@ -206,10 +190,6 @@ class SettingsViewModel : QkViewModel<SettingsView, SettingsState>(SettingsState
.autoDisposable(view.scope())
.subscribe { prefs.textSize.set(it) }
view.notificationPreviewModeSelectedIntent
.autoDisposable(view.scope())
.subscribe { prefs.notificationPreviews().set(it) }
view.mmsSizeSelectedIntent
.doOnNext { view.dismissMmsSizePicker() }
.autoDisposable(view.scope())
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (C) 2017 Moez Bhatti <moez.bhatti@gmail.com>
~
~ This file is part of QKSMS.
@@ -17,67 +16,118 @@
~ You should have received a copy of the GNU General Public License
~ along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.constraint.ConstraintLayout 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:orientation="vertical">
<include layout="@layout/toolbar" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
style="@style/Toolbar"
app:layout_constraintTop_toTopOf="parent"
tools:background="@color/white">
<FrameLayout
android:id="@+id/content"
<common.widget.QkTextView
android:id="@+id/toolbarTitle"
style="@style/ToolbarText"
tools:text="Notifications" />
</android.support.v7.widget.Toolbar>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar">
<ScrollView
<LinearLayout
android:id="@+id/preferences"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical"
android:paddingBottom="8dp"
android:paddingTop="8dp">
<LinearLayout
android:id="@+id/preferences"
<common.widget.PreferenceView
android:id="@+id/notificationsO"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical"
android:paddingBottom="8dp"
android:paddingTop="8dp">
app:icon="@drawable/ic_notifications_black_24dp"
app:title="@string/settings_notifications_title"
tools:visibility="gone" />
<common.widget.PreferenceView
android:id="@+id/notifications"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/settings_notifications_title"
app:widget="@layout/settings_switch_widget" />
<common.widget.PreferenceView
android:id="@+id/notifications"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:icon="@drawable/ic_notifications_black_24dp"
app:title="@string/settings_notifications_title"
app:widget="@layout/settings_switch_widget" />
<common.widget.PreferenceView
android:id="@+id/vibration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/settings_vibration_title"
app:widget="@layout/settings_switch_widget" />
<common.widget.PreferenceView
android:id="@+id/notificationPreviews"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/settings_notification_previews_title"
tools:summary="Show name and message" />
<common.widget.PreferenceView
android:id="@+id/ringtone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/settings_ringtone_title" />
<common.widget.PreferenceView
android:id="@+id/vibration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/settings_vibration_title"
app:widget="@layout/settings_switch_widget" />
</LinearLayout>
<common.widget.PreferenceView
android:id="@+id/ringtone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/settings_ringtone_title" />
</ScrollView>
<common.widget.Separator
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp" />
<View
android:layout_width="match_parent"
android:layout_height="8dp"
android:background="@drawable/ab_shadow" />
<common.widget.QkTextView
style="@style/PreferenceCategory"
android:text="@string/settings_category_qkreply" />
<common.widget.Separator
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="bottom" />
<common.widget.PreferenceView
android:id="@+id/qkreply"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:icon="@drawable/ic_reply_white_24dp"
app:summary="@string/settings_qkreply_summary"
app:title="@string/settings_qkreply_title"
app:widget="@layout/settings_switch_widget" />
</FrameLayout>
<common.widget.PreferenceView
android:id="@+id/qkreplyTapDismiss"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:summary="@string/settings_qkreply_tap_dismiss_summary"
app:title="@string/settings_qkreply_tap_dismiss_title"
app:widget="@layout/settings_switch_widget" />
</LinearLayout>
</LinearLayout>
</ScrollView>
<View
android:layout_width="match_parent"
android:layout_height="8dp"
android:background="@drawable/ab_shadow"
app:layout_constraintTop_toBottomOf="@id/toolbar" />
<common.widget.Separator
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="bottom"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
@@ -144,13 +144,6 @@
app:icon="@drawable/ic_notifications_black_24dp"
app:title="@string/settings_notifications_title" />
<common.widget.PreferenceView
android:id="@+id/notificationPreviews"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/settings_notification_previews_title"
tools:summary="Show name and message" />
<common.widget.PreferenceView
android:id="@+id/autoEmoji"
android:layout_width="match_parent"
@@ -175,23 +168,6 @@
app:title="@string/settings_delivery_title"
app:widget="@layout/settings_switch_widget" />
<common.widget.PreferenceView
android:id="@+id/qkreply"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:icon="@drawable/ic_reply_white_24dp"
app:summary="@string/settings_qkreply_summary"
app:title="@string/settings_qkreply_title"
app:widget="@layout/settings_switch_widget" />
<common.widget.PreferenceView
android:id="@+id/qkreplyTapDismiss"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:summary="@string/settings_qkreply_tap_dismiss_summary"
app:title="@string/settings_qkreply_tap_dismiss_title"
app:widget="@layout/settings_switch_widget" />
<common.widget.PreferenceView
android:id="@+id/unicode"
android:layout_width="match_parent"
@@ -91,6 +91,8 @@
<string name="settings_category_appearance">Appearance</string>
<string name="settings_category_general">General</string>
<string name="settings_category_qkreply">QK Reply</string>
<string name="settings_default_sms_title">Default SMS app</string>
<string name="settings_default_sms_summary_true">QKSMS is your default SMS app</string>
<string name="settings_default_sms_summary_false">Set QKSMS as your default SMS app</string>