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:
Mcommon/src/main/assets/lang/en_US.json | 27+++++++++++++++++++++++++--
Mcommon/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/MessagingTweaks.kt | 2+-
Mcommon/src/main/kotlin/me/rhunk/snapenhance/common/data/SnapEnums.kt | 4+++-
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/messaging/Notifications.kt | 57++++++++++++++++++++++++++++++++++++---------------------
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)) }) }