commit 7c5195e83cc981197fe5f0c59cd74c4a636d8022
parent 5776d4411103691e0f09a2e902cb6e0591a8ccb5
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date:   Fri,  1 Sep 2023 12:30:15 +0200

feat(notifications): groups

Diffstat:
Mcore/src/main/assets/lang/en_US.json | 19++++++++++---------
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/config/impl/Global.kt | 4----
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/config/impl/MessagingTweaks.kt | 4++++
Mcore/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/Notifications.kt | 25+++++++++++++++++++++++--
4 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/core/src/main/assets/lang/en_US.json b/core/src/main/assets/lang/en_US.json @@ -203,6 +203,14 @@ "name": "Prevent Message Sending", "description": "Prevents sending certain types of messages" }, + "better_notifications": { + "name": "Better Notifications", + "description": "Adds more information in received notifications" + }, + "notification_blacklist": { + "name": "Notification Blacklist", + "description": "Select the notifications to be blocked" + }, "message_logger": { "name": "Message Logger", "description": "Keeps messages when someone deletes them. This only works for messages deleted after enabling this feature" @@ -253,14 +261,6 @@ "name": "Force Media Source Quality", "description": "Overrides the media quality to the highest possible" }, - "better_notifications": { - "name": "Better Notifications", - "description": "Adds more information in received notifications" - }, - "notification_blacklist": { - "name": "Notification Blacklist", - "description": "Select the notifications to be blocked" - }, "disable_snap_splitting": { "name": "Disable Snap Splitting", "description": "Prevents Snaps from being split into multiple parts. It also convert sent images into videos" @@ -379,7 +379,8 @@ "chat": "Show chat messages", "snap": "Show medias", "reply_button": "Add reply button", - "download_button": "Add download button" + "download_button": "Add download button", + "group": "Group notifications" }, "friend_feed_menu_buttons": { "auto_download_blacklist": "\u2B07\uFE0F Auto Download Blacklist", diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/config/impl/Global.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/config/impl/Global.kt @@ -12,9 +12,5 @@ class Global : ConfigContainer() { val disableVideoLengthRestrictions = boolean("disable_video_length_restrictions") { addNotices(FeatureNotice.MAY_BAN) } val disableGooglePlayDialogs = boolean("disable_google_play_dialogs") val forceMediaSourceQuality = boolean("force_media_source_quality") - val betterNotifications = multiple("better_notifications", "snap", "chat", "reply_button", "download_button") - val notificationBlacklist = multiple("notification_blacklist", *NotificationType.getIncomingValues().map { it.key }.toTypedArray()) { - customOptionTranslationPath = "features.options.notifications" - } val disableSnapSplitting = boolean("disable_snap_splitting") { addNotices(FeatureNotice.MAY_BREAK_INTERNAL_BEHAVIOR) } } \ No newline at end of file diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/config/impl/MessagingTweaks.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/config/impl/MessagingTweaks.kt @@ -19,6 +19,10 @@ class MessagingTweaks : ConfigContainer() { val preventMessageSending = multiple("prevent_message_sending", *NotificationType.getOutgoingValues().map { it.key }.toTypedArray()) { customOptionTranslationPath = "features.options.notifications" } + val betterNotifications = multiple("better_notifications", "snap", "chat", "reply_button", "download_button", "group") + val notificationBlacklist = multiple("notification_blacklist", *NotificationType.getIncomingValues().map { it.key }.toTypedArray()) { + customOptionTranslationPath = "features.options.notifications" + } val messageLogger = boolean("message_logger") { addNotices(FeatureNotice.MAY_CAUSE_CRASHES) } val galleryMediaSendOverride = boolean("gallery_media_send_override") val messagePreviewLength = integer("message_preview_length", defaultValue = 20) diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/Notifications.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/Notifications.kt @@ -27,6 +27,7 @@ import me.rhunk.snapenhance.hook.HookStage import me.rhunk.snapenhance.hook.Hooker import me.rhunk.snapenhance.hook.hook import me.rhunk.snapenhance.util.CallbackBuilder +import me.rhunk.snapenhance.util.ktx.setObjectField import me.rhunk.snapenhance.util.protobuf.ProtoReader import me.rhunk.snapenhance.util.snap.EncryptionHelper import me.rhunk.snapenhance.util.snap.MediaDownloaderHelper @@ -37,6 +38,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN companion object{ const val ACTION_REPLY = "me.rhunk.snapenhance.action.notification.REPLY" const val ACTION_DOWNLOAD = "me.rhunk.snapenhance.action.notification.DOWNLOAD" + const val SNAPCHAT_NOTIFICATION_GROUP = "snapchat_notification_group" } private val notificationDataQueue = mutableMapOf<Long, NotificationData>() // messageId => notification @@ -62,7 +64,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN } private val betterNotificationFilter by lazy { - context.config.global.betterNotifications.get() + context.config.messaging.betterNotifications.get() } private fun setNotificationText(notification: Notification, conversationId: String) { @@ -185,6 +187,25 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN val sendNotificationData = { notificationData: NotificationData, forceCreate: Boolean -> val notificationId = if (forceCreate) System.nanoTime().toInt() else notificationData.id notificationIdMap.computeIfAbsent(notificationId) { conversationId } + if (betterNotificationFilter.contains("group")) { + runCatching { + notificationData.notification.setObjectField("mGroupKey", SNAPCHAT_NOTIFICATION_GROUP) + + val summaryNotification = Notification.Builder(context.androidContext, notificationData.notification.channelId) + .setSmallIcon(notificationData.notification.smallIcon) + .setGroup(SNAPCHAT_NOTIFICATION_GROUP) + .setGroupSummary(true) + .setAutoCancel(true) + .setOnlyAlertOnce(true) + .build() + + if (notificationManager.activeNotifications.firstOrNull { it.notification.flags and Notification.FLAG_GROUP_SUMMARY != 0 } == null) { + notificationManager.notify(notificationData.tag, notificationData.id, summaryNotification) + } + }.onFailure { + context.log.warn("Failed to set notification group key: ${it.stackTraceToString()}", featureKey) + } + } XposedBridge.invokeOriginalMethod(notifyAsUserMethod, notificationManager, arrayOf( notificationData.tag, if (forceCreate) System.nanoTime().toInt() else notificationData.id, notificationData.notification, notificationData.userHandle @@ -317,7 +338,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN } findClass("com.google.firebase.messaging.FirebaseMessagingService").run { - val states by context.config.global.notificationBlacklist + val states by context.config.messaging.notificationBlacklist methods.first { it.declaringClass == this && it.returnType == Void::class.javaPrimitiveType && it.parameterCount == 1 && it.parameterTypes[0] == Intent::class.java } .hook(HookStage.BEFORE) { param -> val intent = param.argNullable<Intent>(0) ?: return@hook