From c31454b38436bca93c0353d39645209287627d0d Mon Sep 17 00:00:00 2001 From: rhunk <101876869+rhunk@users.noreply.github.com> Date: Thu, 22 Aug 2024 19:19:14 +0200 Subject: [PATCH] fix(core): stealth mode indicator icon --- .../snapenhance/core/event/EventDispatcher.kt | 2 +- .../features/impl/ui/StealthModeIndicator.kt | 45 +++++++++++++++---- .../core/ui/ViewAppearanceHelper.kt | 3 +- .../rhunk/snapenhance/core/ui/ViewTagState.kt | 4 +- 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 index ded4fc4d..6f12102c 100644 --- 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()::class.java ) { - hook(bindMethod.get().toString(), HookStage.AFTER) bindViewMethod@{ param -> + hook(bindMethod.get().toString(), HookStage.BEFORE) bindViewMethod@{ param -> val instance = param.thisObject() 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 index 42d33269..a32954c2 100644 --- 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 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 index 30595a03..b7ab1e7a 100644 --- 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 { 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 index d449a8bd..64b8348e 100644 --- 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)