commit 4bf421441bdfbd2fae3cf658ccc9711a035e2729
parent 81f626cc3be11789f03aac1321cf72ffb11d6a2f
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date: Wed, 8 Nov 2023 19:24:15 +0100
fix(core/better_notifications): handle status message
- add new content types
Diffstat:
4 files changed, 65 insertions(+), 25 deletions(-)
diff --git a/common/src/main/assets/lang/en_US.json b/common/src/main/assets/lang/en_US.json
@@ -605,8 +605,8 @@
"always_dark": "Always Dark"
},
"better_notifications": {
- "chat": "Show chat messages",
- "snap": "Show media",
+ "chat_preview": "Show a preview of chat",
+ "media_preview": "Show a preview of media",
"reply_button": "Add reply button",
"download_button": "Add download button",
"mark_as_read_button": "Mark as Read button",
@@ -722,6 +722,29 @@
"anti_auto_save": "Anti Auto Save"
},
+ "content_type": {
+ "CHAT": "Chat",
+ "SNAP": "Snap",
+ "EXTERNAL_MEDIA": "External Media",
+ "NOTE": "Audio Note",
+ "STICKER": "Sticker",
+ "STATUS": "Status",
+ "LOCATION": "Location",
+ "STATUS_SAVE_TO_CAMERA_ROLL": "Saved to Camera Roll",
+ "STATUS_CONVERSATION_CAPTURE_SCREENSHOT": "Screenshot",
+ "STATUS_CONVERSATION_CAPTURE_RECORD": "Screen Record",
+ "STATUS_CALL_MISSED_VIDEO": "Missed Video Call",
+ "STATUS_CALL_MISSED_AUDIO": "Missed Audio Call",
+ "LIVE_LOCATION_SHARE": "Live Location Share",
+ "CREATIVE_TOOL_ITEM": "Creative Tool Item",
+ "FAMILY_CENTER_INVITE": "Family Center Invite",
+ "FAMILY_CENTER_ACCEPT": "Family Center Accept",
+ "FAMILY_CENTER_LEAVE": "Family Center Leave",
+ "STATUS_PLUS_GIFT": "Status Plus Gift",
+ "TINY_SNAP": "Tiny Snap",
+ "STATUS_COUNTDOWN": "Countdown"
+ },
+
"chat_action_menu": {
"preview_button": "Preview",
"download_button": "Download",
diff --git a/common/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/MessagingTweaks.kt b/common/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/MessagingTweaks.kt
@@ -24,7 +24,7 @@ class MessagingTweaks : ConfigContainer() {
nativeHooks()
}
val instantDelete = boolean("instant_delete") { requireRestart() }
- val betterNotifications = multiple("better_notifications", "snap", "chat", "reply_button", "download_button", "mark_as_read_button", "group") { requireRestart() }
+ val betterNotifications = multiple("better_notifications", "chat_preview", "media_preview", "reply_button", "download_button", "mark_as_read_button", "group") { requireRestart() }
val notificationBlacklist = multiple("notification_blacklist", *NotificationType.getIncomingValues().map { it.key }.toTypedArray()) {
customOptionTranslationPath = "features.options.notifications"
}
diff --git a/common/src/main/kotlin/me/rhunk/snapenhance/common/data/SnapEnums.kt b/common/src/main/kotlin/me/rhunk/snapenhance/common/data/SnapEnums.kt
@@ -71,7 +71,9 @@ enum class ContentType(val id: Int) {
FAMILY_CENTER_INVITE(15),
FAMILY_CENTER_ACCEPT(16),
FAMILY_CENTER_LEAVE(17),
- STATUS_PLUS_GIFT(18);
+ STATUS_PLUS_GIFT(18),
+ TINY_SNAP(19),
+ STATUS_COUNTDOWN(20);
companion object {
fun fromId(i: Int): ContentType {
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/messaging/Notifications.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/messaging/Notifications.kt
@@ -94,7 +94,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
notification
) as Notification.Builder
- private fun setNotificationText(notification: Notification, conversationId: String) {
+ private fun computeNotificationMessages(notification: Notification, conversationId: String) {
val messageText = StringBuilder().apply {
cachedMessages.computeIfAbsent(conversationId) { sortedMapOf() }.forEach {
if (isNotEmpty()) append("\n")
@@ -147,7 +147,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
}
newAction(translations["button.download"], ACTION_DOWNLOAD, {
- betterNotificationFilter.contains("download_button") && (contentType == ContentType.EXTERNAL_MEDIA || contentType == ContentType.SNAP)
+ betterNotificationFilter.contains("download_button") && betterNotificationFilter.contains("media_preview") && (contentType == ContentType.EXTERNAL_MEDIA || contentType == ContentType.SNAP)
}) {}
newAction(translations["button.mark_as_read"], ACTION_MARK_AS_READ, {
@@ -182,7 +182,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
withContext(Dispatchers.Main) {
updateNotification(notificationId) { notification ->
notification.flags = notification.flags or Notification.FLAG_ONLY_ALERT_ONCE
- setNotificationText(notification, conversationId)
+ computeNotificationMessages(notification, conversationId)
}
}
}
@@ -256,7 +256,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
private fun sendNotification(message: Message, notificationData: NotificationData, forceCreate: Boolean) {
val conversationId = message.messageDescriptor?.conversationId.toString()
- val notificationId = if (forceCreate) System.nanoTime().toInt() else notificationData.id
+ val notificationId = if (forceCreate) System.nanoTime().toInt() else message.messageDescriptor?.conversationId?.toBytes().contentHashCode()
sentNotifications.computeIfAbsent(notificationId) { conversationId }
if (betterNotificationFilter.contains("group")) {
@@ -286,7 +286,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
}.send()
}
- private fun onMessageReceived(data: NotificationData, message: Message) {
+ private fun onMessageReceived(data: NotificationData, notificationType: String, message: Message) {
val conversationId = message.messageDescriptor?.conversationId.toString()
val orderKey = message.orderKey ?: return
val senderUsername by lazy {
@@ -295,21 +295,30 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
} ?: "Unknown"
}
- val formatUsername: (String) -> String = { "$senderUsername: $it" }
- val notificationCache = cachedMessages.let { it.computeIfAbsent(conversationId) { sortedMapOf() } }
- val appendNotifications: () -> Unit = { setNotificationText(data.notification, conversationId)}
+ val contentType = message.messageContent!!.contentType!!.let { contentType ->
+ when {
+ notificationType.contains("screenshot") -> ContentType.STATUS_CONVERSATION_CAPTURE_SCREENSHOT
+ else -> contentType
+ }
+ }
+ val computeMessages: () -> Unit = { computeNotificationMessages(data.notification, conversationId)}
+ fun setNotificationText(text: String, includeUsername: Boolean = true) {
+ cachedMessages.computeIfAbsent(conversationId) {
+ sortedMapOf()
+ }[orderKey] = if (includeUsername) "$senderUsername: $text" else text
+ }
- when (val contentType = message.messageContent!!.contentType) {
- ContentType.NOTE -> {
- notificationCache[orderKey] = formatUsername("sent audio note")
- appendNotifications()
- }
+ when (
+ contentType.takeIf {
+ (it != ContentType.SNAP && it != ContentType.EXTERNAL_MEDIA) || betterNotificationFilter.contains("media_preview")
+ } ?: ContentType.UNKNOWN
+ ) {
ContentType.CHAT -> {
ProtoReader(message.messageContent!!.content!!).getString(2, 1)?.trim()?.let {
- notificationCache[orderKey] = formatUsername(it)
+ setNotificationText(it)
}
- appendNotifications()
+ computeMessages()
}
ContentType.SNAP, ContentType.EXTERNAL_MEDIA -> {
val mediaReferences = MessageDecoder.getMediaReferences(
@@ -353,10 +362,11 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
}
}
else -> {
- notificationCache[orderKey] = formatUsername("sent ${contentType?.name?.lowercase()}")
- appendNotifications()
+ setNotificationText("[" + context.translation.getCategory("content_type")[contentType.name] + "]")
+ computeMessages()
}
}
+ if (!betterNotificationFilter.contains("chat_preview")) return
sendNotification(message, data, false)
}
@@ -377,9 +387,8 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
} ?: return@hook
val serverMessageId = extras.getString("message_id") ?: return@hook
- val notificationType = extras.getString("notification_type") ?: return@hook
-
- if (betterNotificationFilter.none { notificationType.contains(it, ignoreCase = true) }) return@hook
+ val notificationType = extras.getString("notification_type")?.lowercase() ?: return@hook
+ if (!betterNotificationFilter.contains("chat_preview") && !betterNotificationFilter.contains("media_preview")) return@hook
param.setResult(null)
val conversationManager = context.feature(Messaging::class).conversationManager ?: return@hook
@@ -387,10 +396,16 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
context.coroutineScope.launch(coroutineDispatcher) {
suspendCoroutine { continuation ->
conversationManager.fetchMessageByServerId(conversationId, serverMessageId, onSuccess = {
- onMessageReceived(notificationData, it)
+ if (it.senderId.toString() == context.database.myUserId) {
+ param.invokeOriginal()
+ continuation.resumeWith(Result.success(Unit))
+ return@fetchMessageByServerId
+ }
+ onMessageReceived(notificationData, notificationType, it)
continuation.resumeWith(Result.success(Unit))
}, onError = {
context.log.error("Failed to fetch message id ${serverMessageId}: $it")
+ param.invokeOriginal()
continuation.resumeWith(Result.success(Unit))
})
}