mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-06-13 05:37:48 +02:00
feat: stealth mode indicator
This commit is contained in:
@ -340,6 +340,10 @@
|
|||||||
"name": "Fidelius Indicator",
|
"name": "Fidelius Indicator",
|
||||||
"description": "Adds a green circle next to messages that have been sent only to you"
|
"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": {
|
"edit_text_override": {
|
||||||
"name": "Edit Text Override",
|
"name": "Edit Text Override",
|
||||||
"description": "Overrides text field behavior"
|
"description": "Overrides text field behavior"
|
||||||
|
@ -49,6 +49,7 @@ class UserInterfaceTweaks : ConfigContainer() {
|
|||||||
val hideSettingsGear = boolean("hide_settings_gear") { requireRestart() }
|
val hideSettingsGear = boolean("hide_settings_gear") { requireRestart() }
|
||||||
val verticalStoryViewer = boolean("vertical_story_viewer") { requireRestart() }
|
val verticalStoryViewer = boolean("vertical_story_viewer") { requireRestart() }
|
||||||
val fideliusIndicator = boolean("fidelius_indicator") { 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") {
|
val editTextOverride = multiple("edit_text_override", "multi_line_chat_input", "bypass_text_input_limit") {
|
||||||
requireRestart(); addNotices(FeatureNotice.BAN_RISK, FeatureNotice.INTERNAL_BEHAVIOR)
|
requireRestart(); addNotices(FeatureNotice.BAN_RISK, FeatureNotice.INTERNAL_BEHAVIOR)
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,11 @@ import me.rhunk.snapenhance.common.data.MessagingRuleType
|
|||||||
import me.rhunk.snapenhance.common.data.RuleState
|
import me.rhunk.snapenhance.common.data.RuleState
|
||||||
|
|
||||||
abstract class MessagingRuleFeature(name: String, val ruleType: MessagingRuleType, loadParams: Int = 0) : Feature(name, loadParams) {
|
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)
|
open fun getRuleState() = context.config.rules.getRuleState(ruleType)
|
||||||
|
|
||||||
@ -13,6 +18,7 @@ abstract class MessagingRuleFeature(name: String, val ruleType: MessagingRuleTyp
|
|||||||
ruleType,
|
ruleType,
|
||||||
state
|
state
|
||||||
)
|
)
|
||||||
|
listeners.forEach { it(conversationId, state) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getState(conversationId: String) =
|
fun getState(conversationId: String) =
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -116,6 +116,7 @@ class FeatureManager(
|
|||||||
ConversationToolbox(),
|
ConversationToolbox(),
|
||||||
SpotlightCommentsUsername(),
|
SpotlightCommentsUsername(),
|
||||||
OperaViewerParamsOverride(),
|
OperaViewerParamsOverride(),
|
||||||
|
StealthModeIndicator(),
|
||||||
)
|
)
|
||||||
|
|
||||||
initializeFeatures()
|
initializeFeatures()
|
||||||
|
Reference in New Issue
Block a user