commit 93490c323c7f39a0945f3aa1b325c0c76d484292
parent 8c71e4af27c7b08e1a8c0901b5efaa5bba4cb3a2
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date:   Wed, 17 Jan 2024 14:53:15 +0100

feat: stealth mode indicator

Diffstat:
Mcommon/src/main/assets/lang/en_US.json | 4++++
Mcommon/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/UserInterfaceTweaks.kt | 1+
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/features/MessagingRuleFeature.kt | 6++++++
Acore/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/ui/StealthModeIndicator.kt | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/manager/impl/FeatureManager.kt | 1+
5 files changed, 90 insertions(+), 0 deletions(-)

diff --git a/common/src/main/assets/lang/en_US.json b/common/src/main/assets/lang/en_US.json @@ -340,6 +340,10 @@ "name": "Fidelius Indicator", "description": "Adds a green circle next to messages that have been sent only to you" }, + "stealth_mode_indicator": { + "name": "Stealth Mode Indicator", + "description": "Adds a \uD83D\uDC7B emoji next to conversations in stealth mode" + }, "edit_text_override": { "name": "Edit Text Override", "description": "Overrides text field behavior" diff --git a/common/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/UserInterfaceTweaks.kt b/common/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/UserInterfaceTweaks.kt @@ -49,6 +49,7 @@ class UserInterfaceTweaks : ConfigContainer() { val hideSettingsGear = boolean("hide_settings_gear") { requireRestart() } val verticalStoryViewer = boolean("vertical_story_viewer") { requireRestart() } val fideliusIndicator = boolean("fidelius_indicator") { requireRestart() } + val stealthModeIndicator = boolean("stealth_mode_indicator") { requireRestart() } val editTextOverride = multiple("edit_text_override", "multi_line_chat_input", "bypass_text_input_limit") { requireRestart(); addNotices(FeatureNotice.BAN_RISK, FeatureNotice.INTERNAL_BEHAVIOR) } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/MessagingRuleFeature.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/MessagingRuleFeature.kt @@ -4,6 +4,11 @@ import me.rhunk.snapenhance.common.data.MessagingRuleType import me.rhunk.snapenhance.common.data.RuleState abstract class MessagingRuleFeature(name: String, val ruleType: MessagingRuleType, loadParams: Int = 0) : Feature(name, loadParams) { + private val listeners = mutableListOf<(String, Boolean) -> Unit>() + + fun addStateListener(listener: (conversationId: String, newState: Boolean) -> Unit) { + listeners.add(listener) + } open fun getRuleState() = context.config.rules.getRuleState(ruleType) @@ -13,6 +18,7 @@ abstract class MessagingRuleFeature(name: String, val ruleType: MessagingRuleTyp ruleType, state ) + listeners.forEach { it(conversationId, state) } } fun getState(conversationId: String) = 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 @@ -0,0 +1,77 @@ +package me.rhunk.snapenhance.core.features.impl.ui + +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.drawable.ShapeDrawable +import android.graphics.drawable.shapes.Shape +import kotlinx.coroutines.Dispatchers +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.FeatureLoadParams +import me.rhunk.snapenhance.core.features.impl.spying.StealthMode +import me.rhunk.snapenhance.core.ui.addForegroundDrawable +import me.rhunk.snapenhance.core.ui.removeForegroundDrawable +import me.rhunk.snapenhance.core.util.EvictingMap +import me.rhunk.snapenhance.core.util.ktx.getDimens +import me.rhunk.snapenhance.core.util.ktx.getIdentifier + +class StealthModeIndicator : Feature("StealthModeIndicator", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) { + 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) + } + } + } + + override fun onActivityCreate() { + if (!context.config.userInterface.stealthModeIndicator.get()) return + + val secondaryTextSize = context.resources.getDimens("ff_feed_cell_secondary_text_size").toFloat() + val sigColorTextPrimary = context.mainActivity!!.obtainStyledAttributes( + intArrayOf(context.resources.getIdentifier("sigColorTextPrimary", "attr")) + ).use { it.getColor(0, 0) } + + stealthMode.addStateListener { conversationId, state -> + runCatching { + listeners[conversationId]?.invoke(state) + }.onFailure { + context.log.error("Failed to update stealth mode indicator", it) + } + } + + context.event.subscribe(BindViewEvent::class) { event -> + fun updateStealthIndicator(isStealth: Boolean = true) { + event.view.removeForegroundDrawable("stealthModeIndicator") + if (!isStealth || !event.view.isAttachedToWindow) return + event.view.addForegroundDrawable("stealthModeIndicator", ShapeDrawable(object : Shape() { + override fun draw(canvas: Canvas, paint: Paint) { + paint.textSize = secondaryTextSize + paint.color = sigColorTextPrimary + canvas.drawText( + "\uD83D\uDC7B", + 0f, + canvas.height.toFloat() - secondaryTextSize / 2, + paint + ) + } + })) + } + + event.friendFeedItem { conversationId -> + listeners[conversationId] = addStateListener@{ stealth -> + updateStealthIndicator(stealth) + } + fetchStealthState(conversationId) { isStealth -> + updateStealthIndicator(isStealth) + } + } + } + } +}+ \ No newline at end of file diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/manager/impl/FeatureManager.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/manager/impl/FeatureManager.kt @@ -116,6 +116,7 @@ class FeatureManager( ConversationToolbox(), SpotlightCommentsUsername(), OperaViewerParamsOverride(), + StealthModeIndicator(), ) initializeFeatures()