mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-05-29 21:10:20 +02:00
refactor: better notifications
- caption in notifications - media preview - stack media messages - fix typing notification
This commit is contained in:
parent
97aed78894
commit
645b7befa9
@ -600,7 +600,49 @@
|
|||||||
},
|
},
|
||||||
"better_notifications": {
|
"better_notifications": {
|
||||||
"name": "Better Notifications",
|
"name": "Better Notifications",
|
||||||
"description": "Adds more information in received notifications"
|
"description": "Adds more information in received notifications",
|
||||||
|
"properties": {
|
||||||
|
"group_notifications": {
|
||||||
|
"name": "Group Notifications",
|
||||||
|
"description": "Group notifications into a single one"
|
||||||
|
},
|
||||||
|
"chat_preview": {
|
||||||
|
"name": "Chat Preview",
|
||||||
|
"description": "Shows a preview of received messages in the notification"
|
||||||
|
},
|
||||||
|
"media_preview": {
|
||||||
|
"name": "Media Preview",
|
||||||
|
"description": "Shows a preview of the selected media types in the notification"
|
||||||
|
},
|
||||||
|
"media_caption": {
|
||||||
|
"name": "Media Caption",
|
||||||
|
"description": "Shows the attached caption of media in the notification"
|
||||||
|
},
|
||||||
|
"stacked_media_messages": {
|
||||||
|
"name": "Stacked Media Messages",
|
||||||
|
"description": "Combines multiple media messages into one text notification when they cannot be previewed. Use in combination with Chat Preview"
|
||||||
|
},
|
||||||
|
"friend_add_source": {
|
||||||
|
"name": "Friend Add Source",
|
||||||
|
"description": "Shows the source of a friend request in the notification"
|
||||||
|
},
|
||||||
|
"reply_button": {
|
||||||
|
"name": "Reply Button",
|
||||||
|
"description": "Adds a reply button to the notification"
|
||||||
|
},
|
||||||
|
"download_button": {
|
||||||
|
"name": "Download Button",
|
||||||
|
"description": "Allows you to download media from the notification"
|
||||||
|
},
|
||||||
|
"mark_as_read_button": {
|
||||||
|
"name": "Mark as Read Button",
|
||||||
|
"description": "Allows you to mark a message as read from the notification"
|
||||||
|
},
|
||||||
|
"mark_as_read_and_save_in_chat": {
|
||||||
|
"name": "Mark as Read and Save in Chat",
|
||||||
|
"description": "Adds a mark as read and save in chat button to the notification"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"notification_blacklist": {
|
"notification_blacklist": {
|
||||||
"name": "Notification Blacklist",
|
"name": "Notification Blacklist",
|
||||||
@ -1048,16 +1090,6 @@
|
|||||||
"always_light": "Always Light",
|
"always_light": "Always Light",
|
||||||
"always_dark": "Always Dark"
|
"always_dark": "Always Dark"
|
||||||
},
|
},
|
||||||
"better_notifications": {
|
|
||||||
"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",
|
|
||||||
"mark_as_read_and_save_in_chat": "Save in Chat when marking as read (depends on Auto Save)",
|
|
||||||
"friend_add_source": "Show friend add source",
|
|
||||||
"group": "Group notifications"
|
|
||||||
},
|
|
||||||
"theme_picker": {
|
"theme_picker": {
|
||||||
"amoled_dark_mode": "AMOLED Dark Mode",
|
"amoled_dark_mode": "AMOLED Dark Mode",
|
||||||
"custom": "Custom Colors",
|
"custom": "Custom Colors",
|
||||||
|
@ -48,6 +48,21 @@ class MessagingTweaks : ConfigContainer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BetterNotifications: ConfigContainer() {
|
||||||
|
val groupNotifications = boolean("group_notifications")
|
||||||
|
val chatPreview = boolean("chat_preview")
|
||||||
|
val mediaPreview = multiple("media_preview", "SNAP", "NOTE", "EXTERNAL_MEDIA", "STICKER") {
|
||||||
|
customOptionTranslationPath = "content_type"
|
||||||
|
}
|
||||||
|
val mediaCaption = boolean("media_caption")
|
||||||
|
val stackedMediaMessages = boolean("stacked_media_messages")
|
||||||
|
val friendAddSource = boolean("friend_add_source")
|
||||||
|
val replyButton = boolean("reply_button") { addNotices(FeatureNotice.UNSTABLE) }
|
||||||
|
val downloadButton = boolean("download_button")
|
||||||
|
val markAsReadButton = boolean("mark_as_read_button") { addNotices(FeatureNotice.UNSTABLE) }
|
||||||
|
val markAsReadAndSaveInChat = boolean("mark_as_read_and_save_in_chat") { addNotices(FeatureNotice.UNSTABLE) }
|
||||||
|
}
|
||||||
|
|
||||||
val bypassScreenshotDetection = boolean("bypass_screenshot_detection") { requireRestart() }
|
val bypassScreenshotDetection = boolean("bypass_screenshot_detection") { requireRestart() }
|
||||||
val anonymousStoryViewing = boolean("anonymous_story_viewing")
|
val anonymousStoryViewing = boolean("anonymous_story_viewing")
|
||||||
val preventStoryRewatchIndicator = boolean("prevent_story_rewatch_indicator") { requireRestart() }
|
val preventStoryRewatchIndicator = boolean("prevent_story_rewatch_indicator") { requireRestart() }
|
||||||
@ -81,16 +96,7 @@ class MessagingTweaks : ConfigContainer() {
|
|||||||
"bitmoji_background_changes",
|
"bitmoji_background_changes",
|
||||||
"bitmoji_scene_changes",
|
"bitmoji_scene_changes",
|
||||||
) { requireRestart() }
|
) { requireRestart() }
|
||||||
val betterNotifications = multiple("better_notifications",
|
val betterNotifications = container("better_notifications", BetterNotifications()) { requireRestart() }
|
||||||
"chat_preview",
|
|
||||||
"media_preview",
|
|
||||||
"reply_button",
|
|
||||||
"download_button",
|
|
||||||
"mark_as_read_button",
|
|
||||||
"mark_as_read_and_save_in_chat",
|
|
||||||
"friend_add_source",
|
|
||||||
"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"
|
||||||
}
|
}
|
||||||
|
@ -574,7 +574,7 @@ class MediaDownloader : MessagingRuleFeature("MediaDownloader", MessagingRuleTyp
|
|||||||
var previewBitmap: Bitmap? = null
|
var previewBitmap: Bitmap? = null
|
||||||
val previewCoroutine = context.coroutineScope.launch {
|
val previewCoroutine = context.coroutineScope.launch {
|
||||||
runCatching {
|
runCatching {
|
||||||
attachment.openStream { attachmentStream ->
|
attachment.openStream { attachmentStream, _ ->
|
||||||
val downloadedMediaList = mutableMapOf<SplitMediaAssetType, ByteArray>()
|
val downloadedMediaList = mutableMapOf<SplitMediaAssetType, ByteArray>()
|
||||||
|
|
||||||
MediaDownloaderHelper.getSplitElements(attachmentStream!!) {
|
MediaDownloaderHelper.getSplitElements(attachmentStream!!) {
|
||||||
|
@ -31,18 +31,21 @@ data class DecodedAttachment(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalEncodingApi::class)
|
@OptIn(ExperimentalEncodingApi::class)
|
||||||
inline fun openStream(crossinline callback: (InputStream?) -> Unit) {
|
inline fun openStream(crossinline callback: (mediaStream: InputStream?, length: Long) -> Unit) {
|
||||||
boltKey?.let { mediaUrlKey ->
|
boltKey?.let { mediaUrlKey ->
|
||||||
RemoteMediaResolver.downloadBoltMedia(Base64.decode(mediaUrlKey), decryptionCallback = {
|
RemoteMediaResolver.downloadBoltMedia(Base64.UrlSafe.decode(mediaUrlKey), decryptionCallback = {
|
||||||
attachmentInfo?.encryption?.decryptInputStream(it) ?: it
|
attachmentInfo?.encryption?.decryptInputStream(it) ?: it
|
||||||
}, resultCallback = { inputStream, _ ->
|
}, resultCallback = { inputStream, length ->
|
||||||
callback(inputStream)
|
callback(inputStream, length)
|
||||||
})
|
})
|
||||||
} ?: directUrl?.let { rawMediaUrl ->
|
} ?: directUrl?.let { rawMediaUrl ->
|
||||||
URL(rawMediaUrl).openStream().let { inputStream ->
|
val connection = URL(rawMediaUrl).openConnection()
|
||||||
attachmentInfo?.encryption?.decryptInputStream(inputStream) ?: inputStream
|
connection.getInputStream().let {
|
||||||
}.use(callback)
|
attachmentInfo?.encryption?.decryptInputStream(it) ?: it
|
||||||
} ?: callback(null)
|
}.use {
|
||||||
|
callback(it, connection.contentLengthLong)
|
||||||
|
}
|
||||||
|
} ?: callback(null, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createInputMedia(
|
fun createInputMedia(
|
||||||
|
@ -14,13 +14,11 @@ import de.robv.android.xposed.XposedBridge
|
|||||||
import de.robv.android.xposed.XposedHelpers
|
import de.robv.android.xposed.XposedHelpers
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import me.rhunk.snapenhance.common.data.ContentType
|
import me.rhunk.snapenhance.common.data.ContentType
|
||||||
import me.rhunk.snapenhance.common.data.MediaReferenceType
|
import me.rhunk.snapenhance.common.data.FileType
|
||||||
import me.rhunk.snapenhance.common.data.MessageUpdate
|
import me.rhunk.snapenhance.common.data.MessageUpdate
|
||||||
import me.rhunk.snapenhance.common.data.NotificationType
|
import me.rhunk.snapenhance.common.data.NotificationType
|
||||||
import me.rhunk.snapenhance.common.data.download.SplitMediaAssetType
|
import me.rhunk.snapenhance.common.data.download.SplitMediaAssetType
|
||||||
import me.rhunk.snapenhance.common.util.protobuf.ProtoReader
|
|
||||||
import me.rhunk.snapenhance.common.util.snap.MediaDownloaderHelper
|
import me.rhunk.snapenhance.common.util.snap.MediaDownloaderHelper
|
||||||
import me.rhunk.snapenhance.common.util.snap.RemoteMediaResolver
|
|
||||||
import me.rhunk.snapenhance.common.util.snap.SnapWidgetBroadcastReceiverHelper
|
import me.rhunk.snapenhance.common.util.snap.SnapWidgetBroadcastReceiverHelper
|
||||||
import me.rhunk.snapenhance.core.event.events.impl.SnapWidgetBroadcastReceiveEvent
|
import me.rhunk.snapenhance.core.event.events.impl.SnapWidgetBroadcastReceiveEvent
|
||||||
import me.rhunk.snapenhance.core.features.Feature
|
import me.rhunk.snapenhance.core.features.Feature
|
||||||
@ -81,10 +79,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val translations by lazy { context.translation.getCategory("better_notifications") }
|
private val translations by lazy { context.translation.getCategory("better_notifications") }
|
||||||
|
private val config by lazy { context.config.messaging.betterNotifications }
|
||||||
private val betterNotificationFilter by lazy {
|
|
||||||
context.config.messaging.betterNotifications.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun newNotificationBuilder(notification: Notification) = XposedHelpers.newInstance(
|
private fun newNotificationBuilder(notification: Notification) = XposedHelpers.newInstance(
|
||||||
Notification.Builder::class.java,
|
Notification.Builder::class.java,
|
||||||
@ -138,7 +133,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
}
|
}
|
||||||
|
|
||||||
newAction(translations["button.reply"], ACTION_REPLY, {
|
newAction(translations["button.reply"], ACTION_REPLY, {
|
||||||
betterNotificationFilter.contains("reply_button") && contentType == ContentType.CHAT
|
config.replyButton.get() && contentType == ContentType.CHAT
|
||||||
}) {
|
}) {
|
||||||
val chatReplyInput = RemoteInput.Builder("chat_reply_input")
|
val chatReplyInput = RemoteInput.Builder("chat_reply_input")
|
||||||
.setLabel(translations["button.reply"])
|
.setLabel(translations["button.reply"])
|
||||||
@ -147,11 +142,11 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
}
|
}
|
||||||
|
|
||||||
newAction(translations["button.download"], ACTION_DOWNLOAD, {
|
newAction(translations["button.download"], ACTION_DOWNLOAD, {
|
||||||
betterNotificationFilter.contains("download_button") && betterNotificationFilter.contains("media_preview") && (contentType == ContentType.EXTERNAL_MEDIA || contentType == ContentType.SNAP)
|
config.downloadButton.get() && config.mediaPreview.get().contains(contentType.name)
|
||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
newAction(translations["button.mark_as_read"], ACTION_MARK_AS_READ, {
|
newAction(translations["button.mark_as_read"], ACTION_MARK_AS_READ, {
|
||||||
betterNotificationFilter.contains("mark_as_read_button")
|
config.markAsReadButton.get()
|
||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
val notificationBuilder = newNotificationBuilder(notificationData.notification).apply {
|
val notificationBuilder = newNotificationBuilder(notificationData.notification).apply {
|
||||||
@ -232,7 +227,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (betterNotificationFilter.contains("mark_as_read_and_save_in_chat")) {
|
if (config.markAsReadAndSaveInChat.get()) {
|
||||||
val messaging = context.feature(Messaging::class)
|
val messaging = context.feature(Messaging::class)
|
||||||
val autoSave = context.feature(AutoSave::class)
|
val autoSave = context.feature(AutoSave::class)
|
||||||
|
|
||||||
@ -285,7 +280,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
val notificationId = if (forceCreate) System.nanoTime().toInt() else message.messageDescriptor?.conversationId?.toBytes().contentHashCode()
|
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 (config.groupNotifications.get()) {
|
||||||
runCatching {
|
runCatching {
|
||||||
if (notificationManager.activeNotifications.firstOrNull {
|
if (notificationManager.activeNotifications.firstOrNull {
|
||||||
it.notification.flags and Notification.FLAG_GROUP_SUMMARY != 0
|
it.notification.flags and Notification.FLAG_GROUP_SUMMARY != 0
|
||||||
@ -336,41 +331,23 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
}[orderKey] = if (includeUsername) "$senderUsername: $text" else text
|
}[orderKey] = if (includeUsername) "$senderUsername: $text" else text
|
||||||
}
|
}
|
||||||
|
|
||||||
when (
|
if (config.mediaPreview.get().contains(contentType.name)) {
|
||||||
contentType.takeIf {
|
MessageDecoder.decode(message.messageContent!!).firstOrNull()?.also { media ->
|
||||||
(it != ContentType.SNAP && it != ContentType.EXTERNAL_MEDIA) || betterNotificationFilter.contains("media_preview")
|
runCatching {
|
||||||
} ?: ContentType.UNKNOWN
|
media.openStream { mediaStream, length ->
|
||||||
) {
|
if (mediaStream == null || length > 25 * 1024 * 1024) {
|
||||||
ContentType.CHAT -> {
|
context.log.error("Failed to open media stream or media is too large")
|
||||||
ProtoReader(message.messageContent!!.content!!).getString(2, 1)?.trim()?.let {
|
sendNotification(message, data, true)
|
||||||
setNotificationText(it)
|
return@openStream
|
||||||
}
|
}
|
||||||
computeMessages()
|
|
||||||
}
|
|
||||||
ContentType.SNAP, ContentType.EXTERNAL_MEDIA -> {
|
|
||||||
val mediaReferences = MessageDecoder.getMediaReferences(
|
|
||||||
messageContent = context.gson.toJsonTree(message.messageContent!!.instanceNonNull())
|
|
||||||
)
|
|
||||||
|
|
||||||
val mediaReferenceKeys = mediaReferences.map { reference ->
|
|
||||||
reference.asJsonObject.getAsJsonArray("mContentObject").map { it.asByte }.toByteArray()
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageDecoder.decode(message.messageContent!!).firstOrNull()?.also { media ->
|
|
||||||
val mediaType = MediaReferenceType.valueOf(mediaReferences.first().asJsonObject["mMediaType"].asString)
|
|
||||||
|
|
||||||
runCatching {
|
|
||||||
val downloadedMedia = RemoteMediaResolver.downloadBoltMedia(mediaReferenceKeys.first(), decryptionCallback = {
|
|
||||||
media.attachmentInfo?.encryption?.decryptInputStream(it) ?: it
|
|
||||||
}) ?: throw Throwable("Unable to download media")
|
|
||||||
|
|
||||||
val downloadedMedias = mutableMapOf<SplitMediaAssetType, ByteArray>()
|
val downloadedMedias = mutableMapOf<SplitMediaAssetType, ByteArray>()
|
||||||
|
|
||||||
MediaDownloaderHelper.getSplitElements(downloadedMedia.inputStream()) { type, inputStream ->
|
MediaDownloaderHelper.getSplitElements(mediaStream) { type, inputStream ->
|
||||||
downloadedMedias[type] = inputStream.readBytes()
|
downloadedMedias[type] = inputStream.readBytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
var bitmapPreview = PreviewUtils.createPreview(downloadedMedias[SplitMediaAssetType.ORIGINAL]!!, mediaType.name.contains("VIDEO"))!!
|
val originalMedia = downloadedMedias[SplitMediaAssetType.ORIGINAL]!!
|
||||||
|
var bitmapPreview = PreviewUtils.createPreview(originalMedia, FileType.fromByteArray(originalMedia).isVideo)!!
|
||||||
|
|
||||||
downloadedMedias[SplitMediaAssetType.OVERLAY]?.let {
|
downloadedMedias[SplitMediaAssetType.OVERLAY]?.let {
|
||||||
bitmapPreview = PreviewUtils.mergeBitmapOverlay(bitmapPreview, BitmapFactory.decodeByteArray(it, 0, it.size))
|
bitmapPreview = PreviewUtils.mergeBitmapOverlay(bitmapPreview, BitmapFactory.decodeByteArray(it, 0, it.size))
|
||||||
@ -381,19 +358,43 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
style = Notification.BigPictureStyle().bigPicture(bitmapPreview).bigLargeIcon(null as Bitmap?)
|
style = Notification.BigPictureStyle().bigPicture(bitmapPreview).bigLargeIcon(null as Bitmap?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.mediaCaption.get()) {
|
||||||
|
message.serialize()?.let {
|
||||||
|
notificationBuilder.setContentText(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sendNotification(message, data.copy(notification = notificationBuilder.build()), true)
|
sendNotification(message, data.copy(notification = notificationBuilder.build()), true)
|
||||||
return
|
|
||||||
}.onFailure {
|
|
||||||
context.log.error("Failed to send preview notification", it)
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}.onFailure {
|
||||||
|
context.log.error("Failed to send preview notification", it)
|
||||||
|
sendNotification(message, data, true)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
|
||||||
setNotificationText("[" + context.translation.getCategory("content_type")[contentType.name] + "]")
|
|
||||||
computeMessages()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!betterNotificationFilter.contains("chat_preview")) return
|
|
||||||
|
if (config.chatPreview.get()) {
|
||||||
|
if (contentType == ContentType.CHAT) {
|
||||||
|
setNotificationText(message.serialize() ?: "[Failed to parse message]")
|
||||||
|
} else {
|
||||||
|
if (config.stackedMediaMessages.get()) {
|
||||||
|
setNotificationText(buildString {
|
||||||
|
append("[")
|
||||||
|
append(context.translation.getCategory("content_type")[contentType.name])
|
||||||
|
append("]")
|
||||||
|
if (config.mediaCaption.get()) {
|
||||||
|
message.serialize()?.let { append(" $it") }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
sendNotification(message, data, true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
computeMessages()
|
||||||
|
}
|
||||||
|
|
||||||
sendNotification(message, data, false)
|
sendNotification(message, data, false)
|
||||||
}
|
}
|
||||||
@ -419,7 +420,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
val notificationData = NotificationData(param.argNullable(0), param.arg(1), param.arg(2), param.arg(3))
|
val notificationData = NotificationData(param.argNullable(0), param.arg(1), param.arg(2), param.arg(3))
|
||||||
val extras = notificationData.notification.extras.getBundle("system_notification_extras")?: return@hook
|
val extras = notificationData.notification.extras.getBundle("system_notification_extras")?: return@hook
|
||||||
|
|
||||||
if (betterNotificationFilter.contains("group")) {
|
if (config.groupNotifications.get()) {
|
||||||
notificationData.notification.setObjectField("mGroupKey", SNAPCHAT_NOTIFICATION_GROUP)
|
notificationData.notification.setObjectField("mGroupKey", SNAPCHAT_NOTIFICATION_GROUP)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,7 +431,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
return@hook
|
return@hook
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notificationType == "addfriend" && betterNotificationFilter.contains("friend_add_source")) {
|
if (notificationType == "addfriend" && config.friendAddSource.get()) {
|
||||||
val userId = notificationData.notification.shortcutId?.split("|")?.lastOrNull() ?: return@hook
|
val userId = notificationData.notification.shortcutId?.split("|")?.lastOrNull() ?: return@hook
|
||||||
runBlocking {
|
runBlocking {
|
||||||
var addSource: String? = null
|
var addSource: String? = null
|
||||||
@ -446,8 +447,8 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
return@hook
|
return@hook
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!betterNotificationFilter.contains("chat_preview") && !betterNotificationFilter.contains("media_preview")) return@hook
|
if (!config.chatPreview.get() && config.mediaPreview.isEmpty()) return@hook
|
||||||
if (notificationType == "typing") return@hook
|
if (notificationType.endsWith("typing")) return@hook
|
||||||
|
|
||||||
val serverMessageId = extras.getString("message_id") ?: return@hook
|
val serverMessageId = extras.getString("message_id") ?: return@hook
|
||||||
val conversationId = extras.getString("conversation_id").also { id ->
|
val conversationId = extras.getString("conversation_id").also { id ->
|
||||||
|
@ -114,7 +114,7 @@ class ConversationExporter(
|
|||||||
for (i in 0..5) {
|
for (i in 0..5) {
|
||||||
printLog("downloading ${attachment.boltKey ?: attachment.directUrl}... (attempt ${i + 1}/5)")
|
printLog("downloading ${attachment.boltKey ?: attachment.directUrl}... (attempt ${i + 1}/5)")
|
||||||
runCatching {
|
runCatching {
|
||||||
attachment.openStream { downloadedInputStream ->
|
attachment.openStream { downloadedInputStream, _ ->
|
||||||
MediaDownloaderHelper.getSplitElements(downloadedInputStream!!) { type, splitInputStream ->
|
MediaDownloaderHelper.getSplitElements(downloadedInputStream!!) { type, splitInputStream ->
|
||||||
val mediaKey = "${type}_${attachment.mediaUniqueId}"
|
val mediaKey = "${type}_${attachment.mediaUniqueId}"
|
||||||
val bufferedInputStream = BufferedInputStream(splitInputStream)
|
val bufferedInputStream = BufferedInputStream(splitInputStream)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user