mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-06-12 21:27:47 +02:00
feat(core): message indicators
This commit is contained in:
@ -112,7 +112,7 @@ class FeatureManager(
|
||||
DisableConfirmationDialogs(),
|
||||
MixerStories(),
|
||||
DisableComposerModules(),
|
||||
FideliusIndicator(),
|
||||
MessageIndicators(),
|
||||
EditTextOverride(),
|
||||
PreventForcedLogout(),
|
||||
SuspendLocationUpdates(),
|
||||
|
@ -1,42 +0,0 @@
|
||||
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 me.rhunk.snapenhance.common.data.ContentType
|
||||
import me.rhunk.snapenhance.common.util.protobuf.ProtoReader
|
||||
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.ui.addForegroundDrawable
|
||||
import me.rhunk.snapenhance.core.ui.removeForegroundDrawable
|
||||
|
||||
class FideliusIndicator : Feature("Fidelius Indicator", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) {
|
||||
override fun onActivityCreate() {
|
||||
if (!context.config.userInterface.fideliusIndicator.get()) return
|
||||
|
||||
context.event.subscribe(BindViewEvent::class) { event ->
|
||||
event.chatMessage { _, messageId ->
|
||||
event.view.removeForegroundDrawable("fideliusIndicator")
|
||||
|
||||
val message = context.database.getConversationMessageFromId(messageId.toLong()) ?: return@chatMessage
|
||||
if (message.senderId == context.database.myUserId) return@chatMessage
|
||||
if (message.contentType != ContentType.SNAP.id && message.contentType != ContentType.EXTERNAL_MEDIA.id) return@chatMessage
|
||||
|
||||
if (!ProtoReader(message.messageContent ?: return@chatMessage).containsPath(4, 3, 3, 6)) return@chatMessage
|
||||
|
||||
event.view.addForegroundDrawable("fideliusIndicator", ShapeDrawable(object: Shape() {
|
||||
override fun draw(canvas: Canvas, paint: Paint) {
|
||||
val margin = 25f
|
||||
val radius = 15f
|
||||
|
||||
canvas.drawCircle(margin + radius, canvas.height - margin - radius, radius, paint.apply {
|
||||
color = 0xFF00FF00.toInt()
|
||||
})
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package me.rhunk.snapenhance.core.features.impl.ui
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Android
|
||||
import androidx.compose.material.icons.filled.Laptop
|
||||
import androidx.compose.material.icons.filled.LocationOn
|
||||
import androidx.compose.material.icons.filled.Lock
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import me.rhunk.snapenhance.common.data.ContentType
|
||||
import me.rhunk.snapenhance.common.ui.createComposeView
|
||||
import me.rhunk.snapenhance.common.util.protobuf.ProtoReader
|
||||
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.ui.AppleLogo
|
||||
import me.rhunk.snapenhance.core.ui.removeForegroundDrawable
|
||||
import kotlin.random.Random
|
||||
|
||||
class MessageIndicators : Feature("Message Indicators", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) {
|
||||
override fun onActivityCreate() {
|
||||
val messageIndicatorsConfig = context.config.userInterface.messageIndicators.getNullable() ?: return
|
||||
if (messageIndicatorsConfig.isEmpty()) return
|
||||
|
||||
val messageInfoTag = Random.nextLong().toString()
|
||||
val appleLogo = AppleLogo
|
||||
|
||||
context.event.subscribe(BindViewEvent::class) { event ->
|
||||
event.chatMessage { _, messageId ->
|
||||
val parentLinearLayout = event.view.parent as? ViewGroup ?: return@subscribe
|
||||
parentLinearLayout.findViewWithTag<View>(messageInfoTag)?.let { parentLinearLayout.removeView(it) }
|
||||
|
||||
event.view.removeForegroundDrawable("messageIndicators")
|
||||
|
||||
val message = context.database.getConversationMessageFromId(messageId.toLong()) ?: return@chatMessage
|
||||
if (message.contentType != ContentType.SNAP.id && message.contentType != ContentType.EXTERNAL_MEDIA.id) return@chatMessage
|
||||
val reader = ProtoReader(message.messageContent ?: return@chatMessage)
|
||||
|
||||
val hasEncryption = if (reader.containsPath(4, 3)) reader.getByteArray(4, 3, 1) == null else false
|
||||
val sentFromIosDevice = if (reader.containsPath(4, 4, 3)) !reader.containsPath(4, 4, 3, 3, 17) else reader.getVarInt(4, 4, 11, 17, 7) != null
|
||||
val sentFromWebApp = reader.getVarInt(4, 4, *(if (reader.containsPath(4, 4, 3)) intArrayOf(3, 3, 22, 1) else intArrayOf(11, 22, 1))) == 7L
|
||||
val sentWithLocation = reader.getVarInt(4, 4, 11, 17, 5) != null
|
||||
|
||||
createComposeView(event.view.context) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 4.dp, end = 1.dp),
|
||||
contentAlignment = Alignment.BottomEnd
|
||||
) {
|
||||
Row {
|
||||
if (messageIndicatorsConfig.contains("location_indicator")) {
|
||||
if (sentWithLocation) {
|
||||
Image(
|
||||
imageVector = Icons.Default.LocationOn,
|
||||
colorFilter = ColorFilter.tint(Color.Green),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(15.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
if (messageIndicatorsConfig.contains("platform_indicator")) {
|
||||
Image(
|
||||
imageVector = when {
|
||||
sentFromWebApp -> Icons.Default.Laptop
|
||||
sentFromIosDevice -> appleLogo
|
||||
else -> Icons.Default.Android
|
||||
},
|
||||
colorFilter = ColorFilter.tint(Color.Green),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(15.dp)
|
||||
)
|
||||
}
|
||||
if (hasEncryption && messageIndicatorsConfig.contains("encryption_indicator")) {
|
||||
Image(
|
||||
imageVector = Icons.Default.Lock,
|
||||
colorFilter = ColorFilter.tint(Color.Green),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(15.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.apply {
|
||||
tag = messageInfoTag
|
||||
addOnLayoutChangeListener { _, left, _, right, _, _, _, _, _ ->
|
||||
layout(left, 0, right, 0)
|
||||
}
|
||||
layoutParams = FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
parentLinearLayout.addView(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package me.rhunk.snapenhance.core.ui
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.PathFillType
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.graphics.StrokeCap
|
||||
import androidx.compose.ui.graphics.StrokeJoin
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.group
|
||||
import androidx.compose.ui.graphics.vector.path
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
|
||||
val AppleLogo: ImageVector
|
||||
get() {
|
||||
return ImageVector.Builder(
|
||||
defaultWidth = 800.dp,
|
||||
defaultHeight = 800.dp,
|
||||
viewportWidth = 27f,
|
||||
viewportHeight = 27f,
|
||||
).apply {
|
||||
group {
|
||||
path(
|
||||
fill = SolidColor(Color(0xFF000000)),
|
||||
fillAlpha = 1.0f,
|
||||
stroke = null,
|
||||
strokeAlpha = 1.0f,
|
||||
strokeLineWidth = 1.0f,
|
||||
strokeLineCap = StrokeCap.Butt,
|
||||
strokeLineJoin = StrokeJoin.Miter,
|
||||
strokeLineMiter = 1.0f,
|
||||
pathFillType = PathFillType.NonZero
|
||||
) {
|
||||
moveTo(15.769f, 0f)
|
||||
curveToRelative(0.053f, 0f, 0.106f, 0f, 0.162f, 0f)
|
||||
curveToRelative(0.13f, 1.606f, -0.483f, 2.806f, -1.228f, 3.675f)
|
||||
curveToRelative(-0.731f, 0.863f, -1.732f, 1.7f, -3.351f, 1.573f)
|
||||
curveToRelative(-0.108f, -1.583f, 0.506f, -2.694f, 1.25f, -3.561f)
|
||||
curveTo(13.292f, 0.879f, 14.557f, 0.16f, 15.769f, 0f)
|
||||
close()
|
||||
}
|
||||
path(
|
||||
fill = SolidColor(Color(0xFF000000)),
|
||||
fillAlpha = 1.0f,
|
||||
stroke = null,
|
||||
strokeAlpha = 1.0f,
|
||||
strokeLineWidth = 1.0f,
|
||||
strokeLineCap = StrokeCap.Butt,
|
||||
strokeLineJoin = StrokeJoin.Miter,
|
||||
strokeLineMiter = 1.0f,
|
||||
pathFillType = PathFillType.NonZero
|
||||
) {
|
||||
moveTo(20.67f, 16.716f)
|
||||
curveToRelative(0f, 0.016f, 0f, 0.03f, 0f, 0.045f)
|
||||
curveToRelative(-0.455f, 1.378f, -1.104f, 2.559f, -1.896f, 3.655f)
|
||||
curveToRelative(-0.723f, 0.995f, -1.609f, 2.334f, -3.191f, 2.334f)
|
||||
curveToRelative(-1.367f, 0f, -2.275f, -0.879f, -3.676f, -0.903f)
|
||||
curveToRelative(-1.482f, -0.024f, -2.297f, 0.735f, -3.652f, 0.926f)
|
||||
curveToRelative(-0.155f, 0f, -0.31f, 0f, -0.462f, 0f)
|
||||
curveToRelative(-0.995f, -0.144f, -1.798f, -0.932f, -2.383f, -1.642f)
|
||||
curveToRelative(-1.725f, -2.098f, -3.058f, -4.808f, -3.306f, -8.276f)
|
||||
curveToRelative(0f, -0.34f, 0f, -0.679f, 0f, -1.019f)
|
||||
curveToRelative(0.105f, -2.482f, 1.311f, -4.5f, 2.914f, -5.478f)
|
||||
curveToRelative(0.846f, -0.52f, 2.009f, -0.963f, 3.304f, -0.765f)
|
||||
curveToRelative(0.555f, 0.086f, 1.122f, 0.276f, 1.619f, 0.464f)
|
||||
curveToRelative(0.471f, 0.181f, 1.06f, 0.502f, 1.618f, 0.485f)
|
||||
curveToRelative(0.378f, -0.011f, 0.754f, -0.208f, 1.135f, -0.347f)
|
||||
curveToRelative(1.116f, -0.403f, 2.21f, -0.865f, 3.652f, -0.648f)
|
||||
curveToRelative(1.733f, 0.262f, 2.963f, 1.032f, 3.723f, 2.22f)
|
||||
curveToRelative(-1.466f, 0.933f, -2.625f, 2.339f, -2.427f, 4.74f)
|
||||
curveTo(17.818f, 14.688f, 19.086f, 15.964f, 20.67f, 16.716f)
|
||||
close()
|
||||
}
|
||||
}
|
||||
}.build()
|
||||
}
|
||||
|
Reference in New Issue
Block a user