feat: special banner borders for team

Signed-off-by: Infi <wingit@geist.ga>
This commit is contained in:
Infi 2023-08-11 00:54:56 +02:00
parent 04237e3dfd
commit 96b0f1a69f
2 changed files with 123 additions and 1 deletions

View File

@ -1,10 +1,96 @@
package chat.revolt.api.internals
import android.content.Context
import android.graphics.RuntimeShader
import android.os.Build
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ShaderBrush
import org.intellij.lang.annotations.Language
import androidx.compose.ui.graphics.Brush as AndroidBrush
object SpecialUsers {
val PLATFORM_MODERATION_USER = "01FC17E1WTM2BGE4F3ARN3FDAF"
val TRUSTED_MODERATION_BOTS = listOf(
"01GXBYCNQ52A9QYCQ99RBPXPAW", // AutoMod
"01FCXRNNVW69AMSHBE61W1M5T3", // AutoMod Nightly
)
sealed class TeamMemberFlair {
data class Brush(val brush: AndroidBrush) : TeamMemberFlair()
data class AGSLShader(val shader: String, val fallback: AndroidBrush) :
TeamMemberFlair()
}
@Language("AGSL")
private val INSERT_SHADER = """
uniform float value;
half4 main(in float2 fragCoord) {
return half4(fragCoord[0] / 1000.0, fragCoord[1] / 1000.0, sin(value), 1.0);
}
""".trimIndent()
val TEAM_MEMBER_FLAIRS = mapOf(
"01F1WKM5TK2V6KCZWR6DGBJDTZ" to TeamMemberFlair.Brush(
AndroidBrush.linearGradient(
listOf(
Color(0xFFD62900),
Color(0xFFFF9B55),
Color(0xFFFFFFFF),
Color(0xFFD461A6),
Color(0xFFA50062),
),
start = Offset.Zero,
end = Offset.Infinite
)
), // jen
"01EX2NCWQ0CHS3QJF0FEQS1GR4" to TeamMemberFlair.AGSLShader(
INSERT_SHADER,
AndroidBrush.linearGradient(
listOf(
Color(0xFF68224F),
Color(0xFFC68235),
),
start = Offset.Zero,
end = Offset.Infinite
)
), // insert
"01EXAF3KX65608AJ4NG27YG1HM" to TeamMemberFlair.Brush(
AndroidBrush.solidColor(Color(0xFFFFC1F1))
), // lea
"01FEEFJCKY5C4DMMJYZ20ACWWC" to TeamMemberFlair.Brush(
AndroidBrush.linearGradient(
listOf(
Color(0xFF0BA39F),
Color(0xFFCD1414)
)
)
), // sophie
"01FD58YK5W7QRV5H3D64KTQYX3" to TeamMemberFlair.Brush(
AndroidBrush.verticalGradient(
listOf(
Color(0xFF980000),
Color(0xFF1000AF)
)
)
), // zomatree
)
fun teamFlairAsBrush(context: Context, id: String): AndroidBrush? {
return when (val flair = TEAM_MEMBER_FLAIRS[id]) {
is TeamMemberFlair.Brush -> flair.brush
is TeamMemberFlair.AGSLShader -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val shader = RuntimeShader(flair.shader)
shader.setFloatUniform("value", (0..1000).random().toFloat())
ShaderBrush(shader)
} else {
flair.fallback
}
null -> null
}
}
}

View File

@ -1,6 +1,7 @@
package chat.revolt.components.screens.settings
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@ -9,6 +10,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@ -18,9 +20,11 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
@ -29,13 +33,17 @@ import androidx.compose.ui.unit.dp
import chat.revolt.R
import chat.revolt.api.REVOLT_FILES
import chat.revolt.api.RevoltAPI
import chat.revolt.api.internals.SpecialUsers
import chat.revolt.api.internals.ULID
import chat.revolt.api.internals.solidColor
import chat.revolt.api.routes.user.fetchUserProfile
import chat.revolt.api.schemas.Profile
import chat.revolt.api.schemas.User
import chat.revolt.components.generic.RemoteImage
import chat.revolt.components.generic.UserAvatar
import chat.revolt.components.generic.presenceFromStatus
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
@Composable
fun SelfUserOverview() {
@ -63,8 +71,36 @@ fun UserOverview(user: User) {
@Composable
fun RawUserOverview(user: User, profile: Profile? = null) {
val context = LocalContext.current
var teamMemberFlair by remember { mutableStateOf<Brush?>(null) }
LaunchedEffect(user) {
runBlocking(Dispatchers.IO) {
user.id?.let {
teamMemberFlair = SpecialUsers.teamFlairAsBrush(
context,
it
)
}
}
}
Box(
contentAlignment = Alignment.BottomStart,
modifier = Modifier
.padding(horizontal = 16.dp)
.clip(MaterialTheme.shapes.large)
.then(
if (user.id in SpecialUsers.TEAM_MEMBER_FLAIRS.keys) {
Modifier
.border(
width = 4.dp,
brush = teamMemberFlair
?: Brush.solidColor(Color.Transparent),
shape = MaterialTheme.shapes.large,
)
} else Modifier
)
) {
profile?.background?.let { background ->
RemoteImage(