mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-07-30 01:43:46 +01:00
Add notifications for scheduled notes to self.
This commit is contained in:
committed by
Michelle Tang
parent
836645ed2b
commit
2d04bb32fd
@@ -2494,15 +2494,22 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
AppDependencies.databaseObserver.notifyMessageUpdateObservers(MessageId(messageId))
|
||||
}
|
||||
|
||||
fun clearScheduledStatus(threadId: Long, messageId: Long, expiresIn: Long): Boolean {
|
||||
fun clearScheduledStatus(threadId: Long, messageId: Long, expiresIn: Long, markUnread: Boolean = false): Boolean {
|
||||
val values = contentValuesOf(
|
||||
SCHEDULED_DATE to -1,
|
||||
DATE_SENT to System.currentTimeMillis(),
|
||||
DATE_RECEIVED to System.currentTimeMillis(),
|
||||
EXPIRES_IN to expiresIn
|
||||
)
|
||||
|
||||
if (markUnread) {
|
||||
values.put(READ, 0)
|
||||
values.put(NOTIFIED, 0)
|
||||
}
|
||||
|
||||
val rowsUpdated = writableDatabase
|
||||
.update(TABLE_NAME)
|
||||
.values(
|
||||
SCHEDULED_DATE to -1,
|
||||
DATE_SENT to System.currentTimeMillis(),
|
||||
DATE_RECEIVED to System.currentTimeMillis(),
|
||||
EXPIRES_IN to expiresIn
|
||||
)
|
||||
.values(values)
|
||||
.where("$ID = ? AND $SCHEDULED_DATE != ?", messageId, -1)
|
||||
.run()
|
||||
|
||||
|
||||
+3
-2
@@ -301,15 +301,16 @@ sealed class NotificationBuilder(protected val context: Context) {
|
||||
|
||||
conversation.notificationItems.forEach { notificationItem ->
|
||||
var person: PersonCompat? = null
|
||||
val isNoteToSelf = notificationItem.isPersonSelf && conversation.recipient.isSelf
|
||||
|
||||
if (!notificationItem.isPersonSelf) {
|
||||
if (!notificationItem.isPersonSelf || isNoteToSelf) {
|
||||
val personBuilder: PersonCompat.Builder = PersonCompat.Builder()
|
||||
.setBot(false)
|
||||
.setName(notificationItem.getPersonName(context))
|
||||
.setUri(notificationItem.getPersonUri(context))
|
||||
.setIcon(notificationItem.getPersonIcon(context))
|
||||
|
||||
if (includeShortcut) {
|
||||
if (includeShortcut && !isNoteToSelf) {
|
||||
personBuilder.setKey(ConversationUtil.getShortcutId(notificationItem.authorRecipient))
|
||||
}
|
||||
|
||||
|
||||
+7
-1
@@ -55,7 +55,11 @@ data class NotificationConversation(
|
||||
|
||||
fun getContactLargeIcon(context: Context): Drawable? {
|
||||
return if (SignalStore.settings.messageNotificationsPrivacy.isDisplayContact) {
|
||||
recipient.getContactDrawable(context)
|
||||
if (recipient.isSelf) {
|
||||
FallbackAvatarDrawable(context, FallbackAvatar.Resource.NoteToSelf(recipient.avatarColor)).circleCrop()
|
||||
} else {
|
||||
recipient.getContactDrawable(context)
|
||||
}
|
||||
} else {
|
||||
FallbackAvatarDrawable(context, FallbackAvatar.forTextOrDefault("Unknown", AvatarColor.UNKNOWN)).circleCrop()
|
||||
}
|
||||
@@ -207,6 +211,8 @@ data class NotificationConversation(
|
||||
private fun getDisplayName(context: Context): String {
|
||||
return if (thread.groupStoryId != null) {
|
||||
context.getString(R.string.SingleRecipientNotificationBuilder__s_dot_story, recipient.getDisplayName(context))
|
||||
} else if (recipient.isSelf) {
|
||||
context.getString(R.string.note_to_self)
|
||||
} else {
|
||||
recipient.getDisplayName(context)
|
||||
}
|
||||
|
||||
+2
-1
@@ -213,8 +213,9 @@ object NotificationFactory {
|
||||
else -> 0.seconds
|
||||
}
|
||||
val canAlertBasedOnTime: Boolean = lastNotificationTimestamp < System.currentTimeMillis() - throttle.inWholeMilliseconds || lastNotificationTimestamp > System.currentTimeMillis()
|
||||
val isUnreadNoteToSelf: Boolean = conversation.recipient.isSelf && (conversation.mostRecentNotification as? MessageNotification)?.isUnread == true
|
||||
|
||||
return ((conversation.hasNewNotifications() && canAlertBasedOnTime) || alertOverride) && !conversation.mostRecentNotification.authorRecipient.isSelf
|
||||
return ((conversation.hasNewNotifications() && canAlertBasedOnTime) || alertOverride) && (!conversation.mostRecentNotification.authorRecipient.isSelf || isUnreadNoteToSelf)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
|
||||
@@ -58,6 +58,9 @@ sealed class NotificationItem(val threadRecipient: Recipient, protected val reco
|
||||
val isPersonSelf: Boolean
|
||||
get() = authorRecipient.isSelf
|
||||
|
||||
protected val isNoteToSelf: Boolean
|
||||
get() = authorRecipient.isSelf && threadRecipient.isSelf
|
||||
|
||||
protected val notifiedTimestamp: Long = record.notifiedTimestamp
|
||||
|
||||
abstract val timestamp: Long
|
||||
@@ -99,7 +102,7 @@ sealed class NotificationItem(val threadRecipient: Recipient, protected val reco
|
||||
context.getString(R.string.SingleRecipientNotificationBuilder_new_message)
|
||||
} else {
|
||||
SpannableStringBuilder().apply {
|
||||
append(Util.getBoldedString(authorRecipient.getShortDisplayName(context)))
|
||||
append(Util.getBoldedString(if (isNoteToSelf) context.getString(R.string.note_to_self) else authorRecipient.getShortDisplayName(context)))
|
||||
if (threadRecipient != authorRecipient) {
|
||||
append(Util.getBoldedString("@${threadRecipient.getDisplayName(context)}"))
|
||||
}
|
||||
@@ -111,7 +114,11 @@ sealed class NotificationItem(val threadRecipient: Recipient, protected val reco
|
||||
|
||||
fun getPersonName(context: Context): CharSequence {
|
||||
return if (SignalStore.settings.messageNotificationsPrivacy.isDisplayContact) {
|
||||
authorRecipient.getDisplayName(context)
|
||||
if (isNoteToSelf) {
|
||||
context.getString(R.string.note_to_self)
|
||||
} else {
|
||||
authorRecipient.getDisplayName(context)
|
||||
}
|
||||
} else {
|
||||
context.getString(R.string.SingleRecipientNotificationBuilder_signal)
|
||||
}
|
||||
@@ -131,7 +138,11 @@ sealed class NotificationItem(val threadRecipient: Recipient, protected val reco
|
||||
|
||||
fun getPersonIcon(context: Context): IconCompat? {
|
||||
return if (SignalStore.settings.messageNotificationsPrivacy.isDisplayContact) {
|
||||
AvatarUtil.getIconCompat(context, authorRecipient)
|
||||
if (isNoteToSelf) {
|
||||
AvatarUtil.getIconCompatForNoteToSelf(context, authorRecipient)
|
||||
} else {
|
||||
AvatarUtil.getIconCompat(context, authorRecipient)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@@ -216,7 +227,7 @@ sealed class NotificationItem(val threadRecipient: Recipient, protected val reco
|
||||
/**
|
||||
* Represents a notification associated with a new message.
|
||||
*/
|
||||
class MessageNotification(threadRecipient: Recipient, record: MessageRecord) : NotificationItem(threadRecipient, record) {
|
||||
class MessageNotification(threadRecipient: Recipient, record: MessageRecord, val isUnread: Boolean = false) : NotificationItem(threadRecipient, record) {
|
||||
override val timestamp: Long = record.timestamp
|
||||
override val authorRecipient: Recipient = record.fromRecipient.resolve()
|
||||
override val isNewNotification: Boolean = notifiedTimestamp == 0L && !record.isEditMessage
|
||||
|
||||
+3
-2
@@ -101,7 +101,7 @@ object NotificationStateProvider {
|
||||
|
||||
for (notification: NotificationMessage in threadMessages) {
|
||||
when (notification.includeMessage(notificationProfile)) {
|
||||
MessageInclusion.INCLUDE -> notificationItems.add(MessageNotification(notification.threadRecipient, notification.messageRecord))
|
||||
MessageInclusion.INCLUDE -> notificationItems.add(MessageNotification(notification.threadRecipient, notification.messageRecord, notification.isUnreadMessage))
|
||||
MessageInclusion.EXCLUDE -> Unit
|
||||
MessageInclusion.MUTE_FILTERED -> muteFilteredMessages += NotificationState.FilteredMessage(notification.messageRecord.id, notification.messageRecord.isMms)
|
||||
MessageInclusion.PROFILE_FILTERED -> profileFilteredMessages += NotificationState.FilteredMessage(notification.messageRecord.id, notification.messageRecord.isMms)
|
||||
@@ -161,6 +161,7 @@ object NotificationStateProvider {
|
||||
) {
|
||||
private val isGroupStoryReply: Boolean = thread.groupStoryId != null
|
||||
private val isUnreadIncoming: Boolean = isUnreadMessage && !messageRecord.isOutgoing && !isGroupStoryReply
|
||||
private val isUnreadNoteToSelf: Boolean = isUnreadMessage && messageRecord.isOutgoing && threadRecipient.isSelf && !isGroupStoryReply
|
||||
private val isIncomingMissedCall: Boolean = !messageRecord.isOutgoing && (messageRecord.isMissedAudioCall || messageRecord.isMissedVideoCall)
|
||||
|
||||
private val isNotifiableGroupStoryMessage: Boolean =
|
||||
@@ -170,7 +171,7 @@ object NotificationStateProvider {
|
||||
(isParentStorySentBySelf || messageRecord.hasGroupQuoteOrSelfMention() || (hasSelfRepliedToStory && !messageRecord.isStoryReaction()))
|
||||
|
||||
fun includeMessage(notificationProfile: NotificationProfile?): MessageInclusion {
|
||||
return if (isUnreadIncoming || stickyThread || isNotifiableGroupStoryMessage || isIncomingMissedCall) {
|
||||
return if (isUnreadIncoming || isUnreadNoteToSelf || stickyThread || isNotifiableGroupStoryMessage || isIncomingMissedCall) {
|
||||
if (threadRecipient.isMuted && !breaksThroughMute()) {
|
||||
MessageInclusion.MUTE_FILTERED
|
||||
} else if (notificationProfile != null && !notificationProfile.isRecipientAllowed(threadRecipient.id) && !(notificationProfile.allowAllMentions && messageRecord.hasGroupQuoteOrSelfMention())) {
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.jobs.IndividualSendJob
|
||||
import org.thoughtcrime.securesms.jobs.PushGroupSendJob
|
||||
import org.thoughtcrime.securesms.notifications.v2.ConversationId
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@@ -55,12 +56,17 @@ class ScheduledMessageManager(
|
||||
val scheduledMessagesToSend = messagesTable.getScheduledMessagesBefore(System.currentTimeMillis())
|
||||
for (record in scheduledMessagesToSend) {
|
||||
val expiresIn = SignalDatabase.recipients.getExpiresInSeconds(record.toRecipient.id)
|
||||
if (messagesTable.clearScheduledStatus(record.threadId, record.id, expiresIn.seconds.inWholeMilliseconds)) {
|
||||
val isNoteToSelf = record.toRecipient.isSelf
|
||||
if (messagesTable.clearScheduledStatus(record.threadId, record.id, expiresIn.seconds.inWholeMilliseconds, markUnread = isNoteToSelf)) {
|
||||
if (record.toRecipient.isPushGroup) {
|
||||
PushGroupSendJob.enqueue(application, AppDependencies.jobManager, record.id, record.toRecipient.id, emptySet(), true)
|
||||
} else {
|
||||
IndividualSendJob.enqueue(application, AppDependencies.jobManager, record.id, record.toRecipient, true)
|
||||
}
|
||||
|
||||
if (isNoteToSelf) {
|
||||
AppDependencies.messageNotifier.updateNotification(application, ConversationId.forConversation(record.threadId))
|
||||
}
|
||||
} else {
|
||||
Log.i(TAG, "messageId=${record.id} was not a scheduled message, ignoring")
|
||||
}
|
||||
|
||||
@@ -128,12 +128,17 @@ public final class AvatarUtil {
|
||||
*/
|
||||
@WorkerThread
|
||||
public static @NonNull IconCompat getIconCompatForShortcut(@NonNull Context context, @NonNull Recipient recipient) {
|
||||
int size = AdaptiveBitmapMetrics.getInnerWidth();
|
||||
if (recipient.isSelf()) {
|
||||
Drawable noteToSelfDrawable = getNoteToSelfDrawable(context, recipient.getAvatarColor(), size);
|
||||
return IconCompat.createWithBitmap(DrawableUtil.toBitmap(noteToSelfDrawable, size, size));
|
||||
return getIconCompatForNoteToSelf(context, recipient);
|
||||
}
|
||||
return IconCompat.createWithBitmap(getBitmapForNotification(context, recipient, size));
|
||||
return IconCompat.createWithBitmap(getBitmapForNotification(context, recipient, AdaptiveBitmapMetrics.getInnerWidth()));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static @NonNull IconCompat getIconCompatForNoteToSelf(@NonNull Context context, @NonNull Recipient recipient) {
|
||||
int size = AdaptiveBitmapMetrics.getInnerWidth();
|
||||
Drawable noteToSelfDrawable = getNoteToSelfDrawable(context, recipient.getAvatarColor(), size);
|
||||
return IconCompat.createWithBitmap(DrawableUtil.toBitmap(noteToSelfDrawable, size, size));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
|
||||
Reference in New Issue
Block a user