commit c31454b38436bca93c0353d39645209287627d0d
parent 2f4817d54c579c88872abe6525e5c51232b1c478
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date: Thu, 22 Aug 2024 19:19:14 +0200
fix(core): stealth mode indicator icon
Diffstat:
4 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/event/EventDispatcher.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/EventDispatcher.kt
@@ -42,7 +42,7 @@ class EventDispatcher(
cacheHook(
methodParam.thisObject<Any>()::class.java
) {
- hook(bindMethod.get().toString(), HookStage.AFTER) bindViewMethod@{ param ->
+ hook(bindMethod.get().toString(), HookStage.BEFORE) bindViewMethod@{ param ->
val instance = param.thisObject<Any>()
val view = instance::class.java.methods.firstOrNull {
it.name == getViewMethod.get().toString()
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/ui/StealthModeIndicator.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/ui/StealthModeIndicator.kt
@@ -6,12 +6,14 @@ import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.Shape
import androidx.core.content.res.use
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import me.rhunk.snapenhance.core.event.events.impl.BindViewEvent
import me.rhunk.snapenhance.core.features.Feature
import me.rhunk.snapenhance.core.features.impl.spying.StealthMode
import me.rhunk.snapenhance.core.ui.addForegroundDrawable
+import me.rhunk.snapenhance.core.ui.randomTag
import me.rhunk.snapenhance.core.ui.removeForegroundDrawable
import me.rhunk.snapenhance.core.util.EvictingMap
import me.rhunk.snapenhance.core.util.ktx.getDimens
@@ -21,15 +23,30 @@ class StealthModeIndicator : Feature("StealthModeIndicator") {
private val stealthMode by lazy { context.feature(StealthMode::class) }
private val listeners = EvictingMap<String, (Boolean) -> Unit>(100)
- private fun fetchStealthState(conversationId: String, result: (Boolean) -> Unit) {
- context.coroutineScope.launch {
- val isStealth = stealthMode.getState(conversationId)
- withContext(Dispatchers.Main) {
- result(isStealth)
+ inner class UpdateHandler {
+ private var fetchJob: Job? = null
+ private var listener = { _: Boolean -> }
+
+ private fun requestUpdate(conversationId: String) {
+ fetchJob?.cancel()
+ fetchJob = context.coroutineScope.launch {
+ val isStealth = stealthMode.getState(conversationId)
+ withContext(Dispatchers.Main) {
+ listener(isStealth)
+ }
+ }
+ }
+
+ fun subscribe(conversationId: String, onStateChange: (Boolean) -> Unit) {
+ listener = onStateChange.also {
+ listeners[conversationId] = it
}
+ requestUpdate(conversationId)
}
}
+ private val stealthModeIndicatorTag = randomTag()
+
override fun init() {
if (!context.config.userInterface.stealthModeIndicator.get()) return
@@ -66,13 +83,23 @@ class StealthModeIndicator : Feature("StealthModeIndicator") {
}
event.friendFeedItem { conversationId ->
- listeners[conversationId] = addStateListener@{ stealth ->
- updateStealthIndicator(stealth)
+ val updateHandler = event.view.getTag(stealthModeIndicatorTag) as? UpdateHandler ?: run {
+ val handler = UpdateHandler()
+ event.view.setTag(stealthModeIndicatorTag, handler)
+ handler
}
- fetchStealthState(conversationId) { isStealth ->
- updateStealthIndicator(isStealth)
+
+ event.view.post {
+ synchronized(listeners) {
+ updateHandler.subscribe(conversationId) { isStealth ->
+ updateStealthIndicator(isStealth)
+ }
+ }
}
+ return@subscribe
}
+
+ event.view.setTag(stealthModeIndicatorTag, null)
}
}
}
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/ViewAppearanceHelper.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/ViewAppearanceHelper.kt
@@ -26,13 +26,12 @@ import me.rhunk.snapenhance.core.util.ktx.getDimensFloat
import me.rhunk.snapenhance.core.util.ktx.getIdentifier
import me.rhunk.snapenhance.core.wrapper.impl.composer.ComposerContext
import me.rhunk.snapenhance.core.wrapper.impl.composer.ComposerViewNode
-import kotlin.random.Random
fun View.applyTheme(componentWidth: Int? = null, hasRadius: Boolean = false, isAmoled: Boolean = true) {
ViewAppearanceHelper.applyTheme(this, componentWidth, hasRadius, isAmoled)
}
-private val foregroundDrawableListTag = Random.nextInt(0x7000000, 0x7FFFFFFF)
+private val foregroundDrawableListTag = randomTag()
@Suppress("UNCHECKED_CAST")
private fun View.getForegroundDrawables(): MutableMap<String, Drawable> {
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/ViewTagState.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/ViewTagState.kt
@@ -3,8 +3,10 @@ package me.rhunk.snapenhance.core.ui
import android.view.View
import kotlin.random.Random
+fun randomTag() = Random.nextInt(0x7000000, 0x7FFFFFFF)
+
class ViewTagState {
- private val tag = Random.nextInt(0x7000000, 0x7FFFFFFF)
+ private val tag = randomTag()
operator fun get(view: View) = hasState(view)