mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-05-28 12:30:12 +02:00
feat: prevent message list auto scroll
This commit is contained in:
parent
bfe367efd0
commit
79be5da030
@ -259,6 +259,10 @@
|
||||
"name": "Enhanced Friend Map Nametags",
|
||||
"description": "Improves the Nametags of friends on the Snapmap"
|
||||
},
|
||||
"prevent_message_list_auto_scroll": {
|
||||
"name": "Prevent Message List Auto Scroll",
|
||||
"description": "Prevents the message list from scrolling to the bottom when sending/receiving a message"
|
||||
},
|
||||
"streak_expiration_info": {
|
||||
"name": "Show Streak Expiration Info",
|
||||
"description": "Shows a Streak Expiration timer next to the Streaks counter"
|
||||
|
@ -29,6 +29,7 @@ class UserInterfaceTweaks : ConfigContainer() {
|
||||
val snapPreview = boolean("snap_preview") { addNotices(FeatureNotice.UNSTABLE); requireRestart() }
|
||||
val bootstrapOverride = container("bootstrap_override", BootstrapOverride()) { requireRestart() }
|
||||
val mapFriendNameTags = boolean("map_friend_nametags") { requireRestart() }
|
||||
val preventMessageListAutoScroll = boolean("prevent_message_list_auto_scroll") { requireRestart(); addNotices(FeatureNotice.UNSTABLE) }
|
||||
val streakExpirationInfo = boolean("streak_expiration_info") { requireRestart() }
|
||||
val hideFriendFeedEntry = boolean("hide_friend_feed_entry") { requireRestart() }
|
||||
val hideStreakRestore = boolean("hide_streak_restore") { requireRestart() }
|
||||
|
@ -0,0 +1,80 @@
|
||||
package me.rhunk.snapenhance.core.features.impl.tweaks
|
||||
|
||||
import android.view.View
|
||||
import me.rhunk.snapenhance.core.event.events.impl.BindViewEvent
|
||||
import me.rhunk.snapenhance.core.features.Feature
|
||||
import me.rhunk.snapenhance.core.features.FeatureLoadParams
|
||||
import me.rhunk.snapenhance.core.util.hook.HookStage
|
||||
import me.rhunk.snapenhance.core.util.hook.hook
|
||||
import me.rhunk.snapenhance.core.wrapper.impl.Message
|
||||
import me.rhunk.snapenhance.core.wrapper.impl.SnapUUID
|
||||
|
||||
class PreventMessageListAutoScroll : Feature("PreventMessageListAutoScroll", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) {
|
||||
private var openedConversationId: String? = null
|
||||
private val focusedMessages = mutableMapOf<View, Long>()
|
||||
private var firstFocusedMessageId: Long? = null
|
||||
private val delayedMessageUpdates = mutableListOf<() -> Unit>()
|
||||
|
||||
override fun onActivityCreate() {
|
||||
if (!context.config.userInterface.preventMessageListAutoScroll.get()) return
|
||||
|
||||
context.mappings.getMappedClass("callbacks", "ConversationManagerDelegate").hook("onConversationUpdated", HookStage.BEFORE) { param ->
|
||||
val updatedMessage = param.arg<ArrayList<*>>(2).map { Message(it) }.firstOrNull() ?: return@hook
|
||||
if (openedConversationId != updatedMessage.messageDescriptor?.conversationId.toString()) return@hook
|
||||
|
||||
// cancel if the message is already in focus
|
||||
if (focusedMessages.entries.any { entry -> entry.value == updatedMessage.messageDescriptor?.messageId && entry.key.isAttachedToWindow }) return@hook
|
||||
|
||||
val conversationLastMessages = context.database.getMessagesFromConversationId(
|
||||
openedConversationId.toString(),
|
||||
4
|
||||
) ?: return@hook
|
||||
|
||||
if (conversationLastMessages.none {
|
||||
focusedMessages.entries.any { entry -> entry.value == it.clientMessageId.toLong() && entry.key.isAttachedToWindow }
|
||||
}) {
|
||||
synchronized(delayedMessageUpdates) {
|
||||
if (firstFocusedMessageId == null) firstFocusedMessageId = conversationLastMessages.lastOrNull()?.clientMessageId?.toLong()
|
||||
delayedMessageUpdates.add {
|
||||
param.invokeOriginal()
|
||||
}
|
||||
}
|
||||
param.setResult(null)
|
||||
}
|
||||
}
|
||||
|
||||
context.classCache.conversationManager.apply {
|
||||
hook("enterConversation", HookStage.BEFORE) { param ->
|
||||
openedConversationId = SnapUUID(param.arg(0)).toString()
|
||||
}
|
||||
hook("exitConversation", HookStage.BEFORE) {
|
||||
openedConversationId = null
|
||||
firstFocusedMessageId = null
|
||||
synchronized(focusedMessages) {
|
||||
focusedMessages.clear()
|
||||
}
|
||||
synchronized(delayedMessageUpdates) {
|
||||
delayedMessageUpdates.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.event.subscribe(BindViewEvent::class) { event ->
|
||||
event.chatMessage { conversationId, messageId ->
|
||||
if (conversationId != openedConversationId) return@chatMessage
|
||||
synchronized(focusedMessages) {
|
||||
focusedMessages[event.view] = messageId.toLong()
|
||||
}
|
||||
|
||||
if (delayedMessageUpdates.isNotEmpty() && focusedMessages.entries.any { entry -> entry.value == firstFocusedMessageId && entry.key.isAttachedToWindow }) {
|
||||
delayedMessageUpdates.apply {
|
||||
synchronized(this) {
|
||||
removeIf { it(); true }
|
||||
firstFocusedMessageId = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ import me.rhunk.snapenhance.core.features.impl.spying.MessageLogger
|
||||
import me.rhunk.snapenhance.core.features.impl.spying.StealthMode
|
||||
import me.rhunk.snapenhance.core.features.impl.tweaks.BypassScreenshotDetection
|
||||
import me.rhunk.snapenhance.core.features.impl.tweaks.CameraTweaks
|
||||
import me.rhunk.snapenhance.core.features.impl.tweaks.PreventMessageListAutoScroll
|
||||
import me.rhunk.snapenhance.core.features.impl.ui.*
|
||||
import me.rhunk.snapenhance.core.logger.CoreLogger
|
||||
import me.rhunk.snapenhance.core.manager.Manager
|
||||
@ -111,6 +112,7 @@ class FeatureManager(
|
||||
Stories::class,
|
||||
DisableComposerModules::class,
|
||||
FideliusIndicator::class,
|
||||
PreventMessageListAutoScroll::class,
|
||||
)
|
||||
|
||||
initializeFeatures()
|
||||
|
Loading…
x
Reference in New Issue
Block a user