diff --git a/app/src/main/java/chat/revolt/api/RevoltAPI.kt b/app/src/main/java/chat/revolt/api/RevoltAPI.kt
index eaad8bfc..8d72f6ea 100644
--- a/app/src/main/java/chat/revolt/api/RevoltAPI.kt
+++ b/app/src/main/java/chat/revolt/api/RevoltAPI.kt
@@ -23,8 +23,13 @@ const val REVOLT_BASE = "https://api.revolt.chat"
const val REVOLT_SUPPORT = "https://support.revolt.chat"
const val REVOLT_MARKETING = "https://revolt.chat"
const val REVOLT_FILES = "https://autumn.revolt.chat"
+const val REVOLT_JANUARY = "https://jan.revolt.chat"
const val REVOLT_WEBSOCKET = "wss://ws.revolt.chat"
+fun asJanuaryProxyUrl(url: String): String {
+ return "$REVOLT_JANUARY/proxy?url=${url}"
+}
+
private const val BACKEND_IS_STABLE = false
val RevoltJson = Json { ignoreUnknownKeys = true }
diff --git a/app/src/main/java/chat/revolt/api/internals/WebCompat.kt b/app/src/main/java/chat/revolt/api/internals/WebCompat.kt
new file mode 100644
index 00000000..ecdcc8ce
--- /dev/null
+++ b/app/src/main/java/chat/revolt/api/internals/WebCompat.kt
@@ -0,0 +1,32 @@
+package chat.revolt.api.internals
+
+import android.util.Log
+import androidx.compose.material3.LocalContentColor
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.graphics.Color
+
+object WebCompat {
+ @Composable
+ fun parseColour(colour: String): Color {
+ if (colour.startsWith("var(")) {
+ return when (colour.substringAfter("var(").substringBefore(")")) {
+ "accent" -> MaterialTheme.colorScheme.primary
+ "foreground" -> MaterialTheme.colorScheme.onBackground
+ "background" -> MaterialTheme.colorScheme.background
+ "error" -> MaterialTheme.colorScheme.error
+ else -> LocalContentColor.current
+ }
+ } else {
+ try {
+ return Color(android.graphics.Color.parseColor(colour))
+ } catch (e: IllegalArgumentException) {
+ Log.d(
+ "WebCompat",
+ "Failed to parse colour $colour, falling back to LocalContentColor.current"
+ )
+ return LocalContentColor.current
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/chat/revolt/components/chat/InReplyTo.kt b/app/src/main/java/chat/revolt/components/chat/InReplyTo.kt
index fe956e46..cc06dfb8 100644
--- a/app/src/main/java/chat/revolt/components/chat/InReplyTo.kt
+++ b/app/src/main/java/chat/revolt/components/chat/InReplyTo.kt
@@ -15,6 +15,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import chat.revolt.R
import chat.revolt.api.RevoltAPI
+import chat.revolt.api.asJanuaryProxyUrl
import chat.revolt.components.generic.UserAvatar
@Composable
@@ -27,6 +28,8 @@ fun InReplyTo(
val message = RevoltAPI.messageCache[messageId]
val author = RevoltAPI.userCache[message?.author ?: ""]
+ val username = message?.masquerade?.name ?: author?.username ?: ""
+
Row(
modifier = modifier
.fillMaxWidth()
@@ -38,22 +41,23 @@ fun InReplyTo(
if (message != null) {
UserAvatar(
- username = author?.username ?: "",
+ username = username,
userId = author?.id ?: "",
avatar = author?.avatar,
+ rawUrl = message.masquerade?.avatar?.let { asJanuaryProxyUrl(it) },
size = 16.dp
)
Text(
text = if (author != null) {
if (withMention) {
- "@${author.username}"
+ "@$username"
} else {
- author.username
+ username
}
} else {
stringResource(id = R.string.unknown)
- } ?: stringResource(id = R.string.unknown),
+ },
fontWeight = FontWeight.Bold,
fontSize = 12.sp,
color = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.9f),
@@ -62,6 +66,15 @@ fun InReplyTo(
modifier = Modifier.padding(horizontal = 4.dp)
)
+ if (message.masquerade != null && author?.bot != null) {
+ InlineBadge(
+ badge = InlineBadge.Masquerade,
+ colour = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.5f),
+ modifier = Modifier.size(8.dp)
+ )
+ Spacer(modifier = Modifier.width(4.dp))
+ }
+
Text(
text = message.content ?: "",
fontSize = 12.sp,
diff --git a/app/src/main/java/chat/revolt/components/chat/InlineBadge.kt b/app/src/main/java/chat/revolt/components/chat/InlineBadge.kt
new file mode 100644
index 00000000..99b6ee0a
--- /dev/null
+++ b/app/src/main/java/chat/revolt/components/chat/InlineBadge.kt
@@ -0,0 +1,40 @@
+package chat.revolt.components.chat
+
+import androidx.compose.material3.Icon
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import chat.revolt.R
+
+enum class InlineBadge {
+ Bot,
+ Masquerade,
+ PlatformModeration,
+ Developer
+}
+
+@Composable
+fun InlineBadge(
+ badge: InlineBadge,
+ modifier: Modifier = Modifier,
+ colour: Color = Color.Unspecified,
+) {
+ when (badge) {
+ InlineBadge.Bot -> Icon(
+ painter = painterResource(id = R.drawable.ic_robot_24dp),
+ contentDescription = stringResource(id = R.string.badge_bot_alt),
+ tint = colour,
+ modifier = modifier
+ )
+ InlineBadge.Masquerade -> Icon(
+ painter = painterResource(id = R.drawable.ic_link_variant_24dp),
+ contentDescription = stringResource(id = R.string.badge_masquerade_alt),
+ tint = colour,
+ modifier = modifier
+ )
+ InlineBadge.PlatformModeration -> TODO()
+ InlineBadge.Developer -> TODO()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/chat/revolt/components/chat/Message.kt b/app/src/main/java/chat/revolt/components/chat/Message.kt
index b1f9466d..2adfcee5 100644
--- a/app/src/main/java/chat/revolt/components/chat/Message.kt
+++ b/app/src/main/java/chat/revolt/components/chat/Message.kt
@@ -3,14 +3,9 @@ package chat.revolt.components.chat
import android.net.Uri
import android.widget.Toast
import androidx.browser.customtabs.CustomTabsIntent
-import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.background
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.combinedClickable
+import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
-import androidx.compose.material3.CircularProgressIndicator
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Text
+import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -26,7 +21,9 @@ import androidx.compose.ui.unit.sp
import chat.revolt.R
import chat.revolt.api.REVOLT_FILES
import chat.revolt.api.RevoltAPI
+import chat.revolt.api.asJanuaryProxyUrl
import chat.revolt.api.internals.ULID
+import chat.revolt.api.internals.WebCompat
import chat.revolt.api.schemas.AutumnResource
import chat.revolt.components.generic.RemoteImage
import chat.revolt.components.generic.UserAvatar
@@ -50,12 +47,6 @@ fun formatLongAsTime(time: Long): String {
val format =
java.text.SimpleDateFormat("dd.MM.yyyy HH:mm:ss", java.util.Locale.getDefault())
- // EQUIVALENT CODE WITH kotlinx.datetime:
-
- // val date = Instant.fromEpochMilliseconds(time)
- // val format = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss")
-
-
return format.format(date)
}
@@ -109,7 +100,8 @@ fun Message(
UserAvatar(
username = author.username ?: "",
userId = author.id!!,
- avatar = author.avatar
+ avatar = author.avatar,
+ rawUrl = message.masquerade?.avatar?.let { asJanuaryProxyUrl(it) }
)
} else {
UserAvatarWidthPlaceholder()
@@ -119,12 +111,25 @@ fun Message(
if (message.tail == false) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
- text = author.username ?: "",
+ text = message.masquerade?.name ?: author.username ?: "",
fontWeight = FontWeight.Bold,
+ color = if (message.masquerade?.colour != null) {
+ WebCompat.parseColour(message.masquerade.colour)
+ } else LocalContentColor.current,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
+ if (message.masquerade != null && author.bot != null) {
+ Spacer(modifier = Modifier.width(5.dp))
+
+ InlineBadge(
+ badge = InlineBadge.Masquerade,
+ colour = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.5f),
+ modifier = Modifier.size(16.dp)
+ )
+ }
+
Spacer(modifier = Modifier.width(5.dp))
Text(
diff --git a/app/src/main/java/chat/revolt/components/generic/UserAvatar.kt b/app/src/main/java/chat/revolt/components/generic/UserAvatar.kt
index 61a113ef..2cd24ad8 100644
--- a/app/src/main/java/chat/revolt/components/generic/UserAvatar.kt
+++ b/app/src/main/java/chat/revolt/components/generic/UserAvatar.kt
@@ -57,6 +57,7 @@ fun UserAvatar(
modifier: Modifier = Modifier,
presence: Presence? = null,
avatar: AutumnResource? = null,
+ rawUrl: String? = null,
size: Dp = 40.dp,
presenceSize: Dp = 16.dp,
) {
@@ -67,7 +68,7 @@ fun UserAvatar(
) {
if (avatar != null) {
RemoteImage(
- url = "$REVOLT_FILES/avatars/${avatar.id!!}/user.png",
+ url = rawUrl ?: "$REVOLT_FILES/avatars/${avatar.id!!}/user.png",
description = stringResource(id = R.string.avatar_alt, username),
contentScale = ContentScale.Crop,
modifier = Modifier
diff --git a/app/src/main/res/drawable/ic_link_variant_24dp.xml b/app/src/main/res/drawable/ic_link_variant_24dp.xml
new file mode 100644
index 00000000..db6947ab
--- /dev/null
+++ b/app/src/main/res/drawable/ic_link_variant_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_robot_24dp.xml b/app/src/main/res/drawable/ic_robot_24dp.xml
new file mode 100644
index 00000000..3a862f18
--- /dev/null
+++ b/app/src/main/res/drawable/ic_robot_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 906020c3..9f4ae91c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -70,7 +70,9 @@
Send
Add attachment
Remove attachment
- Show more
+
+ Bot
+ From linked channel
Welcome to Revolt\'s in-progress Android experience!
Select a server and channel by swiping from the left.