commit 202638841a23b5a2d25d11398c9dd934658ac291
parent c04b99434a7389d28128d66d5fb51c8345eb8c41
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date: Fri, 1 Dec 2023 18:50:11 +0100
feat(core/notifications): save in chat when marking as read
Diffstat:
4 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/common/src/main/assets/lang/en_US.json b/common/src/main/assets/lang/en_US.json
@@ -671,6 +671,7 @@
"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)",
"group": "Group notifications"
},
"friend_feed_menu_buttons": {
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
@@ -28,7 +28,7 @@ class MessagingTweaks : ConfigContainer() {
nativeHooks()
}
val instantDelete = boolean("instant_delete") { requireRestart() }
- val betterNotifications = multiple("better_notifications", "chat_preview", "media_preview", "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", "mark_as_read_and_save_in_chat", "group") { requireRestart() }
val notificationBlacklist = multiple("notification_blacklist", *NotificationType.getIncomingValues().map { it.key }.toTypedArray()) {
customOptionTranslationPath = "features.options.notifications"
}
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/messaging/AutoSave.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/messaging/AutoSave.kt
@@ -15,7 +15,7 @@ import me.rhunk.snapenhance.core.wrapper.impl.Message
import me.rhunk.snapenhance.core.wrapper.impl.SnapUUID
import java.util.concurrent.Executors
-class AutoSave : MessagingRuleFeature("Auto Save", MessagingRuleType.AUTO_SAVE, loadParams = FeatureLoadParams.ACTIVITY_CREATE_ASYNC) {
+class AutoSave : MessagingRuleFeature("Auto Save", MessagingRuleType.AUTO_SAVE, loadParams = FeatureLoadParams.INIT_SYNC) {
private val asyncSaveExecutorService = Executors.newSingleThreadExecutor()
private val messageLogger by lazy { context.feature(MessageLogger::class) }
@@ -25,7 +25,7 @@ class AutoSave : MessagingRuleFeature("Auto Save", MessagingRuleType.AUTO_SAVE,
context.config.messaging.autoSaveMessagesInConversations.get()
}
- private fun saveMessage(conversationId: SnapUUID, message: Message) {
+ fun saveMessage(conversationId: SnapUUID, message: Message) {
val messageId = message.messageDescriptor!!.messageId!!
if (messageLogger.takeIf { it.isEnabled }?.isMessageDeleted(conversationId.toString(), messageId) == true) return
if (message.messageState != MessageState.COMMITTED) return
@@ -48,22 +48,22 @@ class AutoSave : MessagingRuleFeature("Auto Save", MessagingRuleType.AUTO_SAVE,
Thread.sleep(100L)
}
- private fun canSaveMessage(message: Message): Boolean {
- if (context.mainActivity == null || context.isMainActivityPaused) return false
+ fun canSaveMessage(message: Message, headless: Boolean = false): Boolean {
+ if (!headless && (context.mainActivity == null || context.isMainActivityPaused)) return false
if (message.messageMetadata!!.savedBy!!.any { uuid -> uuid.toString() == context.database.myUserId }) return false
val contentType = message.messageContent!!.contentType.toString()
return autoSaveFilter.any { it == contentType }
}
- private fun canSaveInConversation(targetConversationId: String): Boolean {
+ fun canSaveInConversation(targetConversationId: String, headless: Boolean = false): Boolean {
val messaging = context.feature(Messaging::class)
- val openedConversationId = messaging.openedConversationUUID?.toString() ?: return false
-
- if (openedConversationId != targetConversationId) return false
+ if (!headless) {
+ if (messaging.openedConversationUUID?.toString() != targetConversationId) return false
+ }
- if (context.feature(StealthMode::class).canUseRule(openedConversationId)) return false
- if (!canUseRule(openedConversationId)) return false
+ if (context.feature(StealthMode::class).canUseRule(targetConversationId)) return false
+ if (!canUseRule(targetConversationId)) return false
return true
}
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
@@ -37,6 +37,7 @@ import me.rhunk.snapenhance.core.util.ktx.setObjectField
import me.rhunk.snapenhance.core.util.media.PreviewUtils
import me.rhunk.snapenhance.core.wrapper.impl.Message
import me.rhunk.snapenhance.core.wrapper.impl.SnapUUID
+import me.rhunk.snapenhance.core.wrapper.impl.toSnapUUID
import kotlin.coroutines.suspendCoroutine
class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.INIT_SYNC) {
@@ -231,6 +232,31 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
}
)
+ if (betterNotificationFilter.contains("mark_as_read_and_save_in_chat")) {
+ val messaging = context.feature(Messaging::class)
+ val autoSave = context.feature(AutoSave::class)
+
+ if (autoSave.canSaveInConversation(conversationId, headless = true)) {
+ messaging.conversationManager?.fetchConversationWithMessagesPaginated(
+ conversationId,
+ Long.MAX_VALUE,
+ 20,
+ onSuccess = { messages ->
+ messages.reversed().forEach { message ->
+ if (!autoSave.canSaveMessage(message, headless = true)) return@forEach
+ context.coroutineScope.launch(coroutineDispatcher) {
+ autoSave.saveMessage(conversationId.toSnapUUID(), message)
+ }
+ }
+ },
+ onError = {
+ context.log.error("Failed to fetch conversation: $it")
+ context.shortToast("Failed to fetch conversation")
+ }
+ )
+ }
+ }
+
val conversationMessage = context.database.getConversationMessageFromId(clientMessageId) ?: return@subscribe
if (conversationMessage.contentType == ContentType.SNAP.id) {