From 8cb733c013e1d2bc65118f22b8b26b69aa7ff6b5 Mon Sep 17 00:00:00 2001 From: Moez Bhatti Date: Wed, 18 Apr 2018 21:17:34 -0400 Subject: [PATCH] #1026 - Add option to hide message contents --- data/src/main/java/util/Preferences.kt | 13 +++++ .../common/util/NotificationManagerImpl.kt | 57 ++++++++++++------- .../java/feature/settings/SettingsActivity.kt | 20 +++++++ .../java/feature/settings/SettingsState.kt | 1 + .../java/feature/settings/SettingsView.kt | 2 + .../feature/settings/SettingsViewModel.kt | 10 ++++ .../src/main/res/layout/settings_activity.xml | 7 +++ presentation/src/main/res/values/strings.xml | 11 ++++ 8 files changed, 102 insertions(+), 19 deletions(-) diff --git a/data/src/main/java/util/Preferences.kt b/data/src/main/java/util/Preferences.kt index 4bc71ee6..5452b6bc 100644 --- a/data/src/main/java/util/Preferences.kt +++ b/data/src/main/java/util/Preferences.kt @@ -37,6 +37,10 @@ class Preferences @Inject constructor(private val rxPrefs: RxSharedPreferences) const val TEXT_SIZE_NORMAL = 1 const val TEXT_SIZE_LARGE = 2 const val TEXT_SIZE_LARGER = 3 + + const val NOTIFICATION_PREVIEWS_ALL = 0 + const val NOTIFICATION_PREVIEWS_NAME = 1 + const val NOTIFICATION_PREVIEWS_NONE = 2 } val defaultSms = rxPrefs.getBoolean("defaultSms", false) @@ -73,6 +77,15 @@ class Preferences @Inject constructor(private val rxPrefs: RxSharedPreferences) } } + fun notificationPreviews(threadId: Long = 0): Preference { + val default = rxPrefs.getInteger("notification_previews", 0) + + return when (threadId) { + 0L -> default + else -> rxPrefs.getInteger("notification_previews_$threadId", default.get()) + } + } + fun vibration(threadId: Long = 0): Preference { val default = rxPrefs.getBoolean("vibration", true) diff --git a/presentation/src/main/java/common/util/NotificationManagerImpl.kt b/presentation/src/main/java/common/util/NotificationManagerImpl.kt index ef945154..7014dc9e 100644 --- a/presentation/src/main/java/common/util/NotificationManagerImpl.kt +++ b/presentation/src/main/java/common/util/NotificationManagerImpl.kt @@ -97,23 +97,6 @@ class NotificationManagerImpl @Inject constructor( val conversation = messageRepo.getConversation(threadId) ?: return - val style = NotificationCompat.MessagingStyle("Me") - messages.forEach { message -> - val name = if (message.isMe()) null else conversation.getTitle() - style.addMessage(message.getSummary(), message.date, name) - } - - val avatar = conversation.recipients.takeIf { it.size == 1 } - ?.first()?.address - ?.let { address -> - GlideApp.with(context) - .asBitmap() - .circleCrop() - .load(PhoneNumberUtils.stripSeparators(address)) - .submit(64.dpToPx(context), 64.dpToPx(context)) - } - ?.let { futureGet -> tryOrNull { futureGet.get() } } - val contentIntent = Intent(context, ComposeActivity::class.java).putExtra("threadId", threadId) val taskStackBuilder = TaskStackBuilder.create(context) taskStackBuilder.addParentStack(ComposeActivity::class.java) @@ -131,18 +114,54 @@ class NotificationManagerImpl @Inject constructor( .setCategory(NotificationCompat.CATEGORY_MESSAGE) .setColor(colors.themeForConversation(threadId).blockingFirst()) .setPriority(NotificationManagerCompat.IMPORTANCE_MAX) - .setLargeIcon(avatar) .setSmallIcon(R.drawable.ic_notification) .setNumber(messages.size) .setAutoCancel(true) .setContentIntent(contentPI) .setDeleteIntent(seenPI) .addAction(readAction) - .setStyle(style) .setSound(Uri.parse(prefs.ringtone(threadId).get())) .setLights(Color.WHITE, 500, 2000) .setVibrate(if (prefs.vibration(threadId).get()) VIBRATE_PATTERN else longArrayOf(0)) + val messagingStyle = NotificationCompat.MessagingStyle("Me") + messages.forEach { message -> + val name = if (message.isMe()) null else conversation.getTitle() + messagingStyle.addMessage(message.getSummary(), message.date, name) + } + + val avatar = conversation.recipients.takeIf { it.size == 1 } + ?.first()?.address + ?.let { address -> + GlideApp.with(context) + .asBitmap() + .circleCrop() + .load(PhoneNumberUtils.stripSeparators(address)) + .submit(64.dpToPx(context), 64.dpToPx(context)) + } + ?.let { futureGet -> tryOrNull { futureGet.get() } } + + when (prefs.notificationPreviews(threadId).get()) { + Preferences.NOTIFICATION_PREVIEWS_ALL -> { + notification + .setLargeIcon(avatar) + .setStyle(messagingStyle) + } + + Preferences.NOTIFICATION_PREVIEWS_NAME -> { + notification + .setLargeIcon(avatar) + .setContentTitle(conversation.getTitle()) + .setContentText(context.resources.getQuantityString(R.plurals.notification_new_messages, messages.size, messages.size)) + } + + Preferences.NOTIFICATION_PREVIEWS_NONE -> { + notification + .setContentTitle(context.getString(R.string.app_name)) + .setContentText(context.resources.getQuantityString(R.plurals.notification_new_messages, messages.size, messages.size)) + } + } + // Add all of the people from this conversation to the notification, so that the system can // appropriately bypass DND mode conversation.recipients diff --git a/presentation/src/main/java/feature/settings/SettingsActivity.kt b/presentation/src/main/java/feature/settings/SettingsActivity.kt index 7fd663f0..1fdb704d 100644 --- a/presentation/src/main/java/feature/settings/SettingsActivity.kt +++ b/presentation/src/main/java/feature/settings/SettingsActivity.kt @@ -49,6 +49,7 @@ class SettingsActivity : QkThemedActivity(), 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 @@ -58,6 +59,7 @@ class SettingsActivity : QkThemedActivity(), SettingsView { override val startTimeSelectedIntent: Subject> = PublishSubject.create() override val endTimeSelectedIntent: Subject> = PublishSubject.create() override val textSizeSelectedIntent by lazy { textSizeAdapter.menuItemClicks } + override val notificationPreviewModeSelectedIntent by lazy { notificationPreviewModeAdapter.menuItemClicks } override val mmsSizeSelectedIntent: Subject by lazy { mmsSizeAdapter.menuItemClicks } // TODO remove this @@ -86,6 +88,7 @@ class SettingsActivity : QkThemedActivity(), 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) @@ -124,6 +127,7 @@ class SettingsActivity : QkThemedActivity(), 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 @@ -191,6 +195,22 @@ class SettingsActivity : QkThemedActivity(), 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) diff --git a/presentation/src/main/java/feature/settings/SettingsState.kt b/presentation/src/main/java/feature/settings/SettingsState.kt index 852395c8..b0b65a3d 100644 --- a/presentation/src/main/java/feature/settings/SettingsState.kt +++ b/presentation/src/main/java/feature/settings/SettingsState.kt @@ -33,6 +33,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, diff --git a/presentation/src/main/java/feature/settings/SettingsView.kt b/presentation/src/main/java/feature/settings/SettingsView.kt index 4287131c..adb9f095 100644 --- a/presentation/src/main/java/feature/settings/SettingsView.kt +++ b/presentation/src/main/java/feature/settings/SettingsView.kt @@ -31,6 +31,7 @@ interface SettingsView : QkView { val startTimeSelectedIntent: Subject> val endTimeSelectedIntent: Subject> val textSizeSelectedIntent: Subject + val notificationPreviewModeSelectedIntent: Subject val mmsSizeSelectedIntent: Observable fun showNightModeDialog() @@ -39,6 +40,7 @@ interface SettingsView : QkView { fun showStartTimePicker(hour: Int, minute: Int) fun showEndTimePicker(hour: Int, minute: Int) fun showTextSizePicker() + fun showNotificationPreviewModeDialog() fun dismissTextSizePicker() fun showMmsSizePicker() fun dismissMmsSizePicker() diff --git a/presentation/src/main/java/feature/settings/SettingsViewModel.kt b/presentation/src/main/java/feature/settings/SettingsViewModel.kt index 75394e23..c499b15e 100644 --- a/presentation/src/main/java/feature/settings/SettingsViewModel.kt +++ b/presentation/src/main/java/feature/settings/SettingsViewModel.kt @@ -81,6 +81,10 @@ class SettingsViewModel : QkViewModel(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) } } @@ -142,6 +146,8 @@ class SettingsViewModel : QkViewModel(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()) @@ -200,6 +206,10 @@ class SettingsViewModel : QkViewModel(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()) diff --git a/presentation/src/main/res/layout/settings_activity.xml b/presentation/src/main/res/layout/settings_activity.xml index 083bfc7d..fd2aa9a4 100644 --- a/presentation/src/main/res/layout/settings_activity.xml +++ b/presentation/src/main/res/layout/settings_activity.xml @@ -144,6 +144,13 @@ app:icon="@drawable/ic_notifications_black_24dp" app:title="@string/settings_notifications_title" /> + + End time Automatic emoji Notifications + Notification previews Vibration Sound Blocking @@ -184,6 +185,10 @@ Archived conversation You must unlock QKSMS+ to use this + + New message + %s new messages + Message not sent The message to %s failed to send @@ -192,6 +197,12 @@ Always on Automatic + + + Show name and message + Show name + Hide contents + Small