PIN: Add a setting to hide notification content when PIN code is configured
This commit is contained in:
parent
a6cf2b0685
commit
44b2673848
|
@ -12,7 +12,7 @@ Improvements 🙌:
|
|||
- Use cache for user color
|
||||
- Allow using an outdated homeserver, at user's risk (#1972)
|
||||
- Restore small logo on login screens and fix scrolling issue on those screens
|
||||
- PIN Code Improvements. Add more settings (#1985)
|
||||
- PIN Code Improvements: Add more settings: biometrics, grace period, notification content (#1985)
|
||||
|
||||
Bugfix 🐛:
|
||||
- Long message cannot be sent/takes infinite time & blocks other messages #1397
|
||||
|
|
|
@ -27,9 +27,9 @@ import im.vector.app.BuildConfig
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import me.gujun.android.span.span
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.content.ContentUrlResolver
|
||||
import me.gujun.android.span.span
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
|
@ -72,6 +72,8 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
private val currentSession: Session?
|
||||
get() = activeSessionDataSource.currentValue?.orNull()
|
||||
|
||||
private var useCompleteNotificationFormat = vectorPreferences.useCompleteNotificationFormat()
|
||||
|
||||
/**
|
||||
Should be called as soon as a new event is ready to be displayed.
|
||||
The notification corresponding to this event will not be displayed until
|
||||
|
@ -243,8 +245,8 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
roomEvents.add(event)
|
||||
}
|
||||
}
|
||||
is InviteNotifiableEvent -> invitationEvents.add(event)
|
||||
is SimpleNotifiableEvent -> simpleEvents.add(event)
|
||||
is InviteNotifiableEvent -> invitationEvents.add(event)
|
||||
is SimpleNotifiableEvent -> simpleEvents.add(event)
|
||||
else -> Timber.w("Type not handled")
|
||||
}
|
||||
}
|
||||
|
@ -253,6 +255,16 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
|
||||
var globalLastMessageTimestamp = 0L
|
||||
|
||||
val newSettings = vectorPreferences.useCompleteNotificationFormat()
|
||||
if (newSettings != useCompleteNotificationFormat) {
|
||||
// Settings has changed, remove all current notifications
|
||||
notificationUtils.cancelAllNotifications()
|
||||
useCompleteNotificationFormat = newSettings
|
||||
}
|
||||
|
||||
var simpleNotificationRoomCounter = 0
|
||||
var simpleNotificationMessageCounter = 0
|
||||
|
||||
// events have been grouped by roomId
|
||||
for ((roomId, events) in roomIdToEventMap) {
|
||||
// Build the notification for the room
|
||||
|
@ -263,6 +275,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
continue
|
||||
}
|
||||
|
||||
simpleNotificationRoomCounter++
|
||||
val roomName = events[0].roomName ?: events[0].senderName ?: ""
|
||||
|
||||
val roomEventGroupInfo = RoomEventGroupInfo(
|
||||
|
@ -303,6 +316,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
roomEventGroupInfo.hasSmartReplyError = true
|
||||
} else {
|
||||
if (!event.isRedacted) {
|
||||
simpleNotificationMessageCounter++
|
||||
style.addMessage(event.body, event.timestamp, senderPerson)
|
||||
}
|
||||
}
|
||||
|
@ -361,16 +375,18 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
stringProvider.getString(R.string.notification_ticker_text_group, roomName, events.last().senderName, events.last().description)
|
||||
}
|
||||
|
||||
val notification = notificationUtils.buildMessagesListNotification(
|
||||
style,
|
||||
roomEventGroupInfo,
|
||||
largeBitmap,
|
||||
lastMessageTimestamp,
|
||||
myUserDisplayName,
|
||||
tickerText)
|
||||
if (useCompleteNotificationFormat) {
|
||||
val notification = notificationUtils.buildMessagesListNotification(
|
||||
style,
|
||||
roomEventGroupInfo,
|
||||
largeBitmap,
|
||||
lastMessageTimestamp,
|
||||
myUserDisplayName,
|
||||
tickerText)
|
||||
|
||||
// is there an id for this room?
|
||||
notificationUtils.showNotificationMessage(roomId, ROOM_MESSAGES_NOTIFICATION_ID, notification)
|
||||
// is there an id for this room?
|
||||
notificationUtils.showNotificationMessage(roomId, ROOM_MESSAGES_NOTIFICATION_ID, notification)
|
||||
}
|
||||
|
||||
hasNewEvent = true
|
||||
summaryIsNoisy = summaryIsNoisy || roomEventGroupInfo.shouldBing
|
||||
|
@ -383,8 +399,10 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
for (event in invitationEvents) {
|
||||
// We build a invitation notification
|
||||
if (firstTime || !event.hasBeenDisplayed) {
|
||||
val notification = notificationUtils.buildRoomInvitationNotification(event, session.myUserId)
|
||||
notificationUtils.showNotificationMessage(event.roomId, ROOM_INVITATION_NOTIFICATION_ID, notification)
|
||||
if (useCompleteNotificationFormat) {
|
||||
val notification = notificationUtils.buildRoomInvitationNotification(event, session.myUserId)
|
||||
notificationUtils.showNotificationMessage(event.roomId, ROOM_INVITATION_NOTIFICATION_ID, notification)
|
||||
}
|
||||
event.hasBeenDisplayed = true // we can consider it as displayed
|
||||
hasNewEvent = true
|
||||
summaryIsNoisy = summaryIsNoisy || event.noisy
|
||||
|
@ -396,8 +414,10 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
for (event in simpleEvents) {
|
||||
// We build a simple notification
|
||||
if (firstTime || !event.hasBeenDisplayed) {
|
||||
val notification = notificationUtils.buildSimpleEventNotification(event, session.myUserId)
|
||||
notificationUtils.showNotificationMessage(event.eventId, ROOM_EVENT_NOTIFICATION_ID, notification)
|
||||
if (useCompleteNotificationFormat) {
|
||||
val notification = notificationUtils.buildSimpleEventNotification(event, session.myUserId)
|
||||
notificationUtils.showNotificationMessage(event.eventId, ROOM_EVENT_NOTIFICATION_ID, notification)
|
||||
}
|
||||
event.hasBeenDisplayed = true // we can consider it as displayed
|
||||
hasNewEvent = true
|
||||
summaryIsNoisy = summaryIsNoisy || event.noisy
|
||||
|
@ -421,19 +441,72 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
|||
if (eventList.isEmpty() || eventList.all { it.isRedacted }) {
|
||||
notificationUtils.cancelNotificationMessage(null, SUMMARY_NOTIFICATION_ID)
|
||||
} else {
|
||||
// FIXME roomIdToEventMap.size is not correct, this is the number of rooms
|
||||
val nbEvents = roomIdToEventMap.size + simpleEvents.size
|
||||
val sumTitle = stringProvider.getQuantityString(R.plurals.notification_compat_summary_title, nbEvents, nbEvents)
|
||||
summaryInboxStyle.setBigContentTitle(sumTitle)
|
||||
// TODO get latest event?
|
||||
.setSummaryText(stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages, nbEvents, nbEvents))
|
||||
|
||||
val notification = notificationUtils.buildSummaryListNotification(
|
||||
summaryInboxStyle,
|
||||
sumTitle,
|
||||
noisy = hasNewEvent && summaryIsNoisy,
|
||||
lastMessageTimestamp = globalLastMessageTimestamp)
|
||||
if (useCompleteNotificationFormat) {
|
||||
val notification = notificationUtils.buildSummaryListNotification(
|
||||
summaryInboxStyle,
|
||||
sumTitle,
|
||||
noisy = hasNewEvent && summaryIsNoisy,
|
||||
lastMessageTimestamp = globalLastMessageTimestamp)
|
||||
|
||||
notificationUtils.showNotificationMessage(null, SUMMARY_NOTIFICATION_ID, notification)
|
||||
notificationUtils.showNotificationMessage(null, SUMMARY_NOTIFICATION_ID, notification)
|
||||
} else {
|
||||
// Add the simple events as message (?)
|
||||
simpleNotificationMessageCounter += simpleEvents.size
|
||||
val numberOfInvitations = invitationEvents.size
|
||||
|
||||
val privacyTitle = if (numberOfInvitations > 0) {
|
||||
val invitationsStr = stringProvider.getQuantityString(R.plurals.notification_invitations, numberOfInvitations, numberOfInvitations)
|
||||
if (simpleNotificationMessageCounter > 0) {
|
||||
// Invitation and message
|
||||
val messageStr = stringProvider.getQuantityString(R.plurals.room_new_messages_notification, simpleNotificationMessageCounter, simpleNotificationMessageCounter)
|
||||
if (simpleNotificationRoomCounter > 1) {
|
||||
// In several rooms
|
||||
val roomStr = stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages_in_room_rooms, simpleNotificationRoomCounter, simpleNotificationRoomCounter)
|
||||
stringProvider.getString(
|
||||
R.string.notification_unread_notified_messages_in_room_and_invitation,
|
||||
messageStr,
|
||||
roomStr,
|
||||
invitationsStr
|
||||
)
|
||||
} else {
|
||||
// In one room
|
||||
stringProvider.getString(
|
||||
R.string.notification_unread_notified_messages_and_invitation,
|
||||
messageStr,
|
||||
invitationsStr
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// Only invitation
|
||||
invitationsStr
|
||||
}
|
||||
} else {
|
||||
// No invitation, only messages
|
||||
val messageStr = stringProvider.getQuantityString(R.plurals.room_new_messages_notification, simpleNotificationMessageCounter, simpleNotificationMessageCounter)
|
||||
if (simpleNotificationRoomCounter > 1) {
|
||||
// In several rooms
|
||||
val roomStr = stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages_in_room_rooms, simpleNotificationMessageCounter, simpleNotificationMessageCounter)
|
||||
stringProvider.getString(R.string.notification_unread_notified_messages_in_room, messageStr, roomStr)
|
||||
} else {
|
||||
// In one room
|
||||
messageStr
|
||||
}
|
||||
}
|
||||
val notification = notificationUtils.buildSummaryListNotification(
|
||||
style = null,
|
||||
compatSummary = privacyTitle,
|
||||
noisy = hasNewEvent && summaryIsNoisy,
|
||||
lastMessageTimestamp = globalLastMessageTimestamp)
|
||||
|
||||
notificationUtils.showNotificationMessage(null, SUMMARY_NOTIFICATION_ID, notification)
|
||||
}
|
||||
|
||||
if (hasNewEvent && summaryIsNoisy) {
|
||||
try {
|
||||
|
|
|
@ -772,7 +772,7 @@ class NotificationUtils @Inject constructor(private val context: Context,
|
|||
/**
|
||||
* Build the summary notification
|
||||
*/
|
||||
fun buildSummaryListNotification(style: NotificationCompat.InboxStyle,
|
||||
fun buildSummaryListNotification(style: NotificationCompat.InboxStyle?,
|
||||
compatSummary: String,
|
||||
noisy: Boolean,
|
||||
lastMessageTimestamp: Long): Notification {
|
||||
|
|
|
@ -168,6 +168,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||
const val SETTINGS_SECURITY_USE_PIN_CODE_FLAG = "SETTINGS_SECURITY_USE_PIN_CODE_FLAG"
|
||||
private const val SETTINGS_SECURITY_USE_BIOMETRICS_FLAG = "SETTINGS_SECURITY_USE_BIOMETRICS_FLAG"
|
||||
private const val SETTINGS_SECURITY_USE_GRACE_PERIOD_FLAG = "SETTINGS_SECURITY_USE_GRACE_PERIOD_FLAG"
|
||||
const val SETTINGS_SECURITY_USE_COMPLETE_NOTIFICATIONS_FLAG = "SETTINGS_SECURITY_USE_COMPLETE_NOTIFICATIONS_FLAG"
|
||||
|
||||
// other
|
||||
const val SETTINGS_MEDIA_SAVING_PERIOD_KEY = "SETTINGS_MEDIA_SAVING_PERIOD_KEY"
|
||||
|
@ -856,6 +857,14 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||
return defaultPrefs.getBoolean(SETTINGS_SECURITY_USE_GRACE_PERIOD_FLAG, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if Pin code is disabled, or if user set the settings to see full notification content
|
||||
*/
|
||||
fun useCompleteNotificationFormat(): Boolean {
|
||||
return !useFlagPinCode()
|
||||
|| defaultPrefs.getBoolean(SETTINGS_SECURITY_USE_COMPLETE_NOTIFICATIONS_FLAG, true)
|
||||
}
|
||||
|
||||
fun backgroundSyncTimeOut(): Int {
|
||||
return tryOrNull {
|
||||
// The xml pref is saved as a string so use getString and parse
|
||||
|
|
|
@ -22,6 +22,7 @@ import androidx.preference.Preference
|
|||
import androidx.preference.SwitchPreference
|
||||
import im.vector.app.R
|
||||
import im.vector.app.features.navigation.Navigator
|
||||
import im.vector.app.features.notifications.NotificationDrawerManager
|
||||
import im.vector.app.features.pin.PinActivity
|
||||
import im.vector.app.features.pin.PinCodeStore
|
||||
import im.vector.app.features.pin.PinMode
|
||||
|
@ -30,7 +31,8 @@ import javax.inject.Inject
|
|||
|
||||
class VectorSettingsPinFragment @Inject constructor(
|
||||
private val pinCodeStore: PinCodeStore,
|
||||
private val navigator: Navigator
|
||||
private val navigator: Navigator,
|
||||
private val notificationDrawerManager: NotificationDrawerManager
|
||||
) : VectorSettingsBaseFragment() {
|
||||
|
||||
override var titleRes = R.string.settings_security_application_protection_screen_title
|
||||
|
@ -40,8 +42,18 @@ class VectorSettingsPinFragment @Inject constructor(
|
|||
findPreference<SwitchPreference>(VectorPreferences.SETTINGS_SECURITY_USE_PIN_CODE_FLAG)!!
|
||||
}
|
||||
|
||||
private val useCompleteNotificationPref by lazy {
|
||||
findPreference<SwitchPreference>(VectorPreferences.SETTINGS_SECURITY_USE_COMPLETE_NOTIFICATIONS_FLAG)!!
|
||||
}
|
||||
|
||||
override fun bindPref() {
|
||||
refreshPinCodeStatus()
|
||||
|
||||
useCompleteNotificationPref.setOnPreferenceChangeListener { _, _ ->
|
||||
// Refresh the drawer for an immediate effect of this change
|
||||
notificationDrawerManager.refreshNotificationDrawer()
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshPinCodeStatus() {
|
||||
|
|
|
@ -1154,6 +1154,10 @@
|
|||
<item quantity="one">1 room</item>
|
||||
<item quantity="other">%d rooms</item>
|
||||
</plurals>
|
||||
<plurals name="notification_invitations">
|
||||
<item quantity="one">1 invitation</item>
|
||||
<item quantity="other">%d invitations</item>
|
||||
</plurals>
|
||||
|
||||
<plurals name="notification_compat_summary_line_for_room">
|
||||
<item quantity="one">%1$s: 1 message</item>
|
||||
|
@ -1165,6 +1169,8 @@
|
|||
</plurals>
|
||||
|
||||
<string name="notification_unread_notified_messages_in_room">%1$s in %2$s"</string>
|
||||
<string name="notification_unread_notified_messages_in_room_and_invitation">%1$s in %2$s and %3$s"</string>
|
||||
<string name="notification_unread_notified_messages_and_invitation">%1$s and %2$s"</string>
|
||||
<string name="notification_unknown_new_event">New Event</string>
|
||||
<string name="notification_unknown_room_name">Room</string>
|
||||
<string name="notification_new_messages">New Messages</string>
|
||||
|
@ -2574,6 +2580,9 @@
|
|||
<string name="settings_security_pin_code_use_biometrics_title">Use biometrics</string>
|
||||
<string name="settings_security_pin_code_use_biometrics_summary_on">Depending on your device, you will be able to unlock using fingerprints, face recognition, iris recognition, etc.</string>
|
||||
<string name="settings_security_pin_code_use_biometrics_summary_off">PIN code is the only way to unlock the application.</string>
|
||||
<string name="settings_security_pin_code_notifications_title">Display complete notifications</string>
|
||||
<string name="settings_security_pin_code_notifications_summary_on">Show full notification details, including rooms details and message contents.</string>
|
||||
<string name="settings_security_pin_code_notifications_summary_off">Only display number of unread messages in a simple notification.</string>
|
||||
<string name="settings_security_pin_code_grace_period_title">Enable grace period</string>
|
||||
<string name="settings_security_pin_code_grace_period_summary_on">PIN code will be asked after 2 minutes not using the application.</string>
|
||||
<string name="settings_security_pin_code_grace_period_summary_off">PIN code will be requested every time you put the application to foreground.</string>
|
||||
|
|
|
@ -15,6 +15,14 @@
|
|||
android:summaryOn="@string/settings_security_pin_code_use_biometrics_summary_on"
|
||||
android:title="@string/settings_security_pin_code_use_biometrics_title" />
|
||||
|
||||
<im.vector.app.core.preference.VectorSwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:dependency="SETTINGS_SECURITY_USE_PIN_CODE_FLAG"
|
||||
android:key="SETTINGS_SECURITY_USE_COMPLETE_NOTIFICATIONS_FLAG"
|
||||
android:summaryOff="@string/settings_security_pin_code_notifications_summary_off"
|
||||
android:summaryOn="@string/settings_security_pin_code_notifications_summary_on"
|
||||
android:title="@string/settings_security_pin_code_notifications_title" />
|
||||
|
||||
<im.vector.app.core.preference.VectorSwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:dependency="SETTINGS_SECURITY_USE_PIN_CODE_FLAG"
|
||||
|
|
Loading…
Reference in New Issue