mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-06-13 05:37:48 +02:00
fix(core/better_notifications): handle status message
- add new content types
This commit is contained in:
@ -605,8 +605,8 @@
|
|||||||
"always_dark": "Always Dark"
|
"always_dark": "Always Dark"
|
||||||
},
|
},
|
||||||
"better_notifications": {
|
"better_notifications": {
|
||||||
"chat": "Show chat messages",
|
"chat_preview": "Show a preview of chat",
|
||||||
"snap": "Show media",
|
"media_preview": "Show a preview of media",
|
||||||
"reply_button": "Add reply button",
|
"reply_button": "Add reply button",
|
||||||
"download_button": "Add download button",
|
"download_button": "Add download button",
|
||||||
"mark_as_read_button": "Mark as Read button",
|
"mark_as_read_button": "Mark as Read button",
|
||||||
@ -722,6 +722,29 @@
|
|||||||
"anti_auto_save": "Anti Auto Save"
|
"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": {
|
"chat_action_menu": {
|
||||||
"preview_button": "Preview",
|
"preview_button": "Preview",
|
||||||
"download_button": "Download",
|
"download_button": "Download",
|
||||||
|
@ -24,7 +24,7 @@ class MessagingTweaks : ConfigContainer() {
|
|||||||
nativeHooks()
|
nativeHooks()
|
||||||
}
|
}
|
||||||
val instantDelete = boolean("instant_delete") { requireRestart() }
|
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()) {
|
val notificationBlacklist = multiple("notification_blacklist", *NotificationType.getIncomingValues().map { it.key }.toTypedArray()) {
|
||||||
customOptionTranslationPath = "features.options.notifications"
|
customOptionTranslationPath = "features.options.notifications"
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,9 @@ enum class ContentType(val id: Int) {
|
|||||||
FAMILY_CENTER_INVITE(15),
|
FAMILY_CENTER_INVITE(15),
|
||||||
FAMILY_CENTER_ACCEPT(16),
|
FAMILY_CENTER_ACCEPT(16),
|
||||||
FAMILY_CENTER_LEAVE(17),
|
FAMILY_CENTER_LEAVE(17),
|
||||||
STATUS_PLUS_GIFT(18);
|
STATUS_PLUS_GIFT(18),
|
||||||
|
TINY_SNAP(19),
|
||||||
|
STATUS_COUNTDOWN(20);
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromId(i: Int): ContentType {
|
fun fromId(i: Int): ContentType {
|
||||||
|
@ -94,7 +94,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
notification
|
notification
|
||||||
) as Notification.Builder
|
) as Notification.Builder
|
||||||
|
|
||||||
private fun setNotificationText(notification: Notification, conversationId: String) {
|
private fun computeNotificationMessages(notification: Notification, conversationId: String) {
|
||||||
val messageText = StringBuilder().apply {
|
val messageText = StringBuilder().apply {
|
||||||
cachedMessages.computeIfAbsent(conversationId) { sortedMapOf() }.forEach {
|
cachedMessages.computeIfAbsent(conversationId) { sortedMapOf() }.forEach {
|
||||||
if (isNotEmpty()) append("\n")
|
if (isNotEmpty()) append("\n")
|
||||||
@ -147,7 +147,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
}
|
}
|
||||||
|
|
||||||
newAction(translations["button.download"], ACTION_DOWNLOAD, {
|
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, {
|
newAction(translations["button.mark_as_read"], ACTION_MARK_AS_READ, {
|
||||||
@ -182,7 +182,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
updateNotification(notificationId) { notification ->
|
updateNotification(notificationId) { notification ->
|
||||||
notification.flags = notification.flags or Notification.FLAG_ONLY_ALERT_ONCE
|
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) {
|
private fun sendNotification(message: Message, notificationData: NotificationData, forceCreate: Boolean) {
|
||||||
val conversationId = message.messageDescriptor?.conversationId.toString()
|
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 }
|
sentNotifications.computeIfAbsent(notificationId) { conversationId }
|
||||||
|
|
||||||
if (betterNotificationFilter.contains("group")) {
|
if (betterNotificationFilter.contains("group")) {
|
||||||
@ -286,7 +286,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
}.send()
|
}.send()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onMessageReceived(data: NotificationData, message: Message) {
|
private fun onMessageReceived(data: NotificationData, notificationType: String, message: Message) {
|
||||||
val conversationId = message.messageDescriptor?.conversationId.toString()
|
val conversationId = message.messageDescriptor?.conversationId.toString()
|
||||||
val orderKey = message.orderKey ?: return
|
val orderKey = message.orderKey ?: return
|
||||||
val senderUsername by lazy {
|
val senderUsername by lazy {
|
||||||
@ -295,21 +295,30 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
} ?: "Unknown"
|
} ?: "Unknown"
|
||||||
}
|
}
|
||||||
|
|
||||||
val formatUsername: (String) -> String = { "$senderUsername: $it" }
|
val contentType = message.messageContent!!.contentType!!.let { contentType ->
|
||||||
val notificationCache = cachedMessages.let { it.computeIfAbsent(conversationId) { sortedMapOf() } }
|
when {
|
||||||
val appendNotifications: () -> Unit = { setNotificationText(data.notification, conversationId)}
|
notificationType.contains("screenshot") -> ContentType.STATUS_CONVERSATION_CAPTURE_SCREENSHOT
|
||||||
|
else -> contentType
|
||||||
|
|
||||||
when (val contentType = message.messageContent!!.contentType) {
|
|
||||||
ContentType.NOTE -> {
|
|
||||||
notificationCache[orderKey] = formatUsername("sent audio note")
|
|
||||||
appendNotifications()
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
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 (
|
||||||
|
contentType.takeIf {
|
||||||
|
(it != ContentType.SNAP && it != ContentType.EXTERNAL_MEDIA) || betterNotificationFilter.contains("media_preview")
|
||||||
|
} ?: ContentType.UNKNOWN
|
||||||
|
) {
|
||||||
ContentType.CHAT -> {
|
ContentType.CHAT -> {
|
||||||
ProtoReader(message.messageContent!!.content!!).getString(2, 1)?.trim()?.let {
|
ProtoReader(message.messageContent!!.content!!).getString(2, 1)?.trim()?.let {
|
||||||
notificationCache[orderKey] = formatUsername(it)
|
setNotificationText(it)
|
||||||
}
|
}
|
||||||
appendNotifications()
|
computeMessages()
|
||||||
}
|
}
|
||||||
ContentType.SNAP, ContentType.EXTERNAL_MEDIA -> {
|
ContentType.SNAP, ContentType.EXTERNAL_MEDIA -> {
|
||||||
val mediaReferences = MessageDecoder.getMediaReferences(
|
val mediaReferences = MessageDecoder.getMediaReferences(
|
||||||
@ -353,10 +362,11 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
notificationCache[orderKey] = formatUsername("sent ${contentType?.name?.lowercase()}")
|
setNotificationText("[" + context.translation.getCategory("content_type")[contentType.name] + "]")
|
||||||
appendNotifications()
|
computeMessages()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!betterNotificationFilter.contains("chat_preview")) return
|
||||||
|
|
||||||
sendNotification(message, data, false)
|
sendNotification(message, data, false)
|
||||||
}
|
}
|
||||||
@ -377,9 +387,8 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
} ?: return@hook
|
} ?: return@hook
|
||||||
|
|
||||||
val serverMessageId = extras.getString("message_id") ?: return@hook
|
val serverMessageId = extras.getString("message_id") ?: return@hook
|
||||||
val notificationType = extras.getString("notification_type") ?: return@hook
|
val notificationType = extras.getString("notification_type")?.lowercase() ?: return@hook
|
||||||
|
if (!betterNotificationFilter.contains("chat_preview") && !betterNotificationFilter.contains("media_preview")) return@hook
|
||||||
if (betterNotificationFilter.none { notificationType.contains(it, ignoreCase = true) }) return@hook
|
|
||||||
|
|
||||||
param.setResult(null)
|
param.setResult(null)
|
||||||
val conversationManager = context.feature(Messaging::class).conversationManager ?: return@hook
|
val conversationManager = context.feature(Messaging::class).conversationManager ?: return@hook
|
||||||
@ -387,10 +396,16 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
context.coroutineScope.launch(coroutineDispatcher) {
|
context.coroutineScope.launch(coroutineDispatcher) {
|
||||||
suspendCoroutine { continuation ->
|
suspendCoroutine { continuation ->
|
||||||
conversationManager.fetchMessageByServerId(conversationId, serverMessageId, onSuccess = {
|
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))
|
continuation.resumeWith(Result.success(Unit))
|
||||||
}, onError = {
|
}, onError = {
|
||||||
context.log.error("Failed to fetch message id ${serverMessageId}: $it")
|
context.log.error("Failed to fetch message id ${serverMessageId}: $it")
|
||||||
|
param.invokeOriginal()
|
||||||
continuation.resumeWith(Result.success(Unit))
|
continuation.resumeWith(Result.success(Unit))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user