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 5a50e79c..09b7624e 100644
--- a/app/src/main/java/chat/revolt/components/chat/Message.kt
+++ b/app/src/main/java/chat/revolt/components/chat/Message.kt
@@ -36,6 +36,7 @@ import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.key
+import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -44,6 +45,7 @@ import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
@@ -181,53 +183,20 @@ fun Message(
// do nothing
}
)
+
+ val authorIsBlocked = remember(author) { author.relationship == "Blocked" }
+
Column {
if (message.tail == false) {
Spacer(modifier = Modifier.height(10.dp))
}
- Column(
- modifier = Modifier.then(
- if (message.mentions?.contains(RevoltAPI.selfId) == true) {
- Modifier.background(
- MaterialTheme.colorScheme.primary.copy(alpha = 0.1f)
- )
- } else {
- Modifier
- }
- )
- ) {
- message.replies?.forEach { reply ->
- val replyMessage = RevoltAPI.messageCache[reply]
-
- message.channel?.let { chId ->
- InReplyTo(
- channelId = chId,
- messageId = reply,
- withMention = replyMessage?.author?.let {
- message.mentions?.contains(
- replyMessage.author
- )
- }
- ?: false
- ) {
- // TODO Add jump to message
- if (replyMessage == null) {
- Toast.makeText(context, "lmao prankd", Toast.LENGTH_SHORT).show()
- }
- }
- }
- }
-
+ if (authorIsBlocked) {
Row(
modifier = Modifier
.combinedClickable(
onClick = {},
- onDoubleClick = {
- if (canReply && GlobalState.messageReplyStyle == MessageReplyStyle.DoubleTap) {
- onReply()
- }
- },
+ onDoubleClick = {},
onLongClick = {
onMessageContextMenu()
}
@@ -235,206 +204,289 @@ fun Message(
.padding(horizontal = 10.dp)
.fillMaxWidth()
) {
- if (message.tail == false) {
- Column {
- Spacer(modifier = Modifier.height(4.dp))
- UserAvatar(
- username = User.resolveDefaultName(author),
- userId = author.id ?: message.id ?: ULID.makeSpecial(0),
- avatar = author.avatar,
- rawUrl = authorAvatarUrl(message),
- onClick = onAvatarClick
- )
- }
- } else {
- UserAvatarWidthPlaceholder()
- }
+ UserAvatarWidthPlaceholder()
Column(modifier = Modifier.padding(start = 10.dp)) {
- if (message.tail == false) {
- Row(verticalAlignment = Alignment.CenterVertically) {
- Text(
- text = authorName(message),
- style = LocalTextStyle.current.copy(
- fontWeight = FontWeight.Bold,
- brush = authorColour(message)
- ),
- maxLines = 1,
- overflow = TextOverflow.Ellipsis,
- modifier = Modifier.then(
- if (onNameClick != null)
- Modifier.combinedClickable(
- onClick = onNameClick,
- onLongClick = {
- onMessageContextMenu()
- }
- )
- else Modifier
- )
- )
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.padding(vertical = 8.dp)
+ ) {
+ Icon(
+ painter = painterResource(R.drawable.ic_close_octagon_24dp),
+ contentDescription = null
+ )
- InlineBadges(
- bot = author.bot != null && message.masquerade == null,
- bridge = message.masquerade != null && author.bot != null,
- platformModeration = author.id == SpecialUsers.PLATFORM_MODERATION_USER,
- teamMember = author.id in SpecialUsers.TEAM_MEMBER_FLAIRS.keys,
- colour = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.5f),
- modifier = Modifier.size(16.dp),
- precedingIfAny = {
- Spacer(modifier = Modifier.width(5.dp))
- }
- )
+ Text(
+ text = stringResource(R.string.message_blocked),
+ fontSize = 12.sp,
+ color = LocalContentColor.current.copy(alpha = 0.5f),
+ fontStyle = FontStyle.Italic
+ )
+ }
+ }
+ }
+ } else {
+ Column(
+ modifier = Modifier.then(
+ if (message.mentions?.contains(RevoltAPI.selfId) == true) {
+ Modifier.background(
+ MaterialTheme.colorScheme.primary.copy(alpha = 0.1f)
+ )
+ } else {
+ Modifier
+ }
+ )
+ ) {
+ message.replies?.forEach { reply ->
+ val replyMessage = RevoltAPI.messageCache[reply]
- Spacer(modifier = Modifier.width(5.dp))
-
- Text(
- text = formatLongAsTime(ULID.asTimestamp(message.id!!)),
- fontSize = 12.sp,
- color = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.5f),
- maxLines = 1,
- overflow = TextOverflow.Ellipsis
- )
-
- Spacer(modifier = Modifier.width(2.dp))
-
- if (message.edited != null) {
- Icon(
- imageVector = Icons.Default.Edit,
- contentDescription = stringResource(id = R.string.edited),
- tint = MaterialTheme.colorScheme.onBackground.copy(
- alpha = 0.5f
- ),
- modifier = Modifier.size(16.dp)
+ message.channel?.let { chId ->
+ InReplyTo(
+ channelId = chId,
+ messageId = reply,
+ withMention = replyMessage?.author?.let {
+ message.mentions?.contains(
+ replyMessage.author
)
}
- }
- }
-
- key(message.content) {
- message.content?.let {
- if (message.content.isBlank()) return@let // if only an attachment is sent
-
- CompositionLocalProvider(
- LocalMarkdownTreeConfig provides LocalMarkdownTreeConfig.current.copy(
- currentServer = RevoltAPI.channelCache[message.channel]?.server
- ),
- LocalTextStyle provides LocalTextStyle.current.copy(
- lineHeight = 25.sp,
- )
- ) {
- RichMarkdown(input = message.content)
- }
- }
- }
-
- message.attachments?.let {
- message.attachments.forEach { attachment ->
- Spacer(modifier = Modifier.height(2.dp))
- MessageAttachment(attachment) {
- when (attachment.metadata?.type) {
- "Image" -> {
- attachmentView.launch(
- Intent(context, ImageViewActivity::class.java).apply {
- putExtra("autumnResource", attachment)
- }
- )
- }
-
- "Video" -> {
- attachmentView.launch(
- Intent(context, VideoViewActivity::class.java).apply {
- putExtra("autumnResource", attachment)
- }
- )
- }
-
- "Audio" -> {
- /* no-op */
- }
-
- else -> {
- viewAttachmentInBrowser(context, attachment)
- }
- }
- }
- Spacer(modifier = Modifier.height(2.dp))
- }
- }
-
- message.embeds?.let {
- message.embeds.forEach { embed ->
- val embedIsEmpty =
- embed.title == null && embed.description == null && embed.iconURL == null && embed.image == null
-
- if (embedIsEmpty) {
- // if we do not emit anything, compose will cause an internal error.
- // FIXME if you are doing fixme's anyways then check if this is still an issue
- Box {}
- return@forEach
- }
-
- Spacer(modifier = Modifier.height(8.dp))
- Embed(embed = embed, onLinkClick = {
- viewUrlInBrowser(context, it)
- })
- Spacer(modifier = Modifier.height(8.dp))
- }
-
- }
-
- if ((message.reactions?.size ?: 0) > 0) {
- Spacer(modifier = Modifier.height(8.dp))
- FlowRow(
- horizontalArrangement = Arrangement.spacedBy(8.dp),
- verticalArrangement = Arrangement.spacedBy(8.dp)
+ ?: false
) {
- message.reactions?.forEach { reaction ->
- Reaction(reaction.key, reaction.value,
- onClick = { hasOwn ->
- scope.launch {
- if (hasOwn) {
- unreact(
- message.channel!!,
- message.id!!,
- reaction.key
- )
- } else {
- react(
- message.channel!!,
- message.id!!,
- reaction.key
- )
- }
+ // TODO Add jump to message
+ if (replyMessage == null) {
+ Toast.makeText(context, "lmao prankd", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+ }
+
+ Row(
+ modifier = Modifier
+ .combinedClickable(
+ onClick = {},
+ onDoubleClick = {
+ if (canReply && GlobalState.messageReplyStyle == MessageReplyStyle.DoubleTap) {
+ onReply()
+ }
+ },
+ onLongClick = {
+ onMessageContextMenu()
+ }
+ )
+ .padding(horizontal = 10.dp)
+ .fillMaxWidth()
+ ) {
+ if (message.tail == false) {
+ Column {
+ Spacer(modifier = Modifier.height(4.dp))
+ UserAvatar(
+ username = User.resolveDefaultName(author),
+ userId = author.id ?: message.id ?: ULID.makeSpecial(0),
+ avatar = author.avatar,
+ rawUrl = authorAvatarUrl(message),
+ onClick = onAvatarClick
+ )
+ }
+ } else {
+ UserAvatarWidthPlaceholder()
+ }
+
+ Column(modifier = Modifier.padding(start = 10.dp)) {
+ if (message.tail == false) {
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Text(
+ text = authorName(message),
+ style = LocalTextStyle.current.copy(
+ fontWeight = FontWeight.Bold,
+ brush = authorColour(message)
+ ),
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ modifier = Modifier.then(
+ if (onNameClick != null)
+ Modifier.combinedClickable(
+ onClick = onNameClick,
+ onLongClick = {
+ onMessageContextMenu()
+ }
+ )
+ else Modifier
+ )
+ )
+
+ InlineBadges(
+ bot = author.bot != null && message.masquerade == null,
+ bridge = message.masquerade != null && author.bot != null,
+ platformModeration = author.id == SpecialUsers.PLATFORM_MODERATION_USER,
+ teamMember = author.id in SpecialUsers.TEAM_MEMBER_FLAIRS.keys,
+ colour = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.5f),
+ modifier = Modifier.size(16.dp),
+ precedingIfAny = {
+ Spacer(modifier = Modifier.width(5.dp))
+ }
+ )
+
+ Spacer(modifier = Modifier.width(5.dp))
+
+ Text(
+ text = formatLongAsTime(ULID.asTimestamp(message.id!!)),
+ fontSize = 12.sp,
+ color = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.5f),
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis
+ )
+
+ Spacer(modifier = Modifier.width(2.dp))
+
+ if (message.edited != null) {
+ Icon(
+ imageVector = Icons.Default.Edit,
+ contentDescription = stringResource(id = R.string.edited),
+ tint = MaterialTheme.colorScheme.onBackground.copy(
+ alpha = 0.5f
+ ),
+ modifier = Modifier.size(16.dp)
+ )
+ }
+ }
+ }
+
+ key(message.content) {
+ message.content?.let {
+ if (message.content.isBlank()) return@let // if only an attachment is sent
+
+ CompositionLocalProvider(
+ LocalMarkdownTreeConfig provides LocalMarkdownTreeConfig.current.copy(
+ currentServer = RevoltAPI.channelCache[message.channel]?.server
+ ),
+ LocalTextStyle provides LocalTextStyle.current.copy(
+ lineHeight = 25.sp,
+ )
+ ) {
+ RichMarkdown(input = message.content)
+ }
+ }
+ }
+
+ message.attachments?.let {
+ message.attachments.forEach { attachment ->
+ Spacer(modifier = Modifier.height(2.dp))
+ MessageAttachment(attachment) {
+ when (attachment.metadata?.type) {
+ "Image" -> {
+ attachmentView.launch(
+ Intent(
+ context,
+ ImageViewActivity::class.java
+ ).apply {
+ putExtra("autumnResource", attachment)
+ }
+ )
+ }
+
+ "Video" -> {
+ attachmentView.launch(
+ Intent(
+ context,
+ VideoViewActivity::class.java
+ ).apply {
+ putExtra("autumnResource", attachment)
+ }
+ )
+ }
+
+ "Audio" -> {
+ /* no-op */
+ }
+
+ else -> {
+ viewAttachmentInBrowser(context, attachment)
}
}
- ) {
- scope.launch {
- ActionChannel.send(
- Action.MessageReactionInfo(
- message.id!!,
- reaction.key
- )
- )
- }
}
- }
-
- Row(
- verticalAlignment = Alignment.CenterVertically,
- modifier = Modifier
- .clip(MaterialTheme.shapes.small)
- .background(MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp))
- .clickable(onClick = onAddReaction)
- .padding(8.dp)
- ) {
- Icon(
- painter = painterResource(R.drawable.ic_hamburger_plus_24dp),
- contentDescription = stringResource(R.string.message_context_sheet_actions_react),
- modifier = Modifier.size(16.dp)
- )
+ Spacer(modifier = Modifier.height(2.dp))
}
}
- Spacer(modifier = Modifier.height(8.dp))
+
+ message.embeds?.let {
+ message.embeds.forEach { embed ->
+ val embedIsEmpty =
+ embed.title == null && embed.description == null && embed.iconURL == null && embed.image == null
+
+ if (embedIsEmpty) {
+ // if we do not emit anything, compose will cause an internal error.
+ // FIXME if you are doing fixme's anyways then check if this is still an issue
+ Box {}
+ return@forEach
+ }
+
+ Spacer(modifier = Modifier.height(8.dp))
+ Embed(embed = embed, onLinkClick = {
+ viewUrlInBrowser(context, it)
+ })
+ Spacer(modifier = Modifier.height(8.dp))
+ }
+
+ }
+
+ if ((message.reactions?.size ?: 0) > 0) {
+ Spacer(modifier = Modifier.height(8.dp))
+ FlowRow(
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ verticalArrangement = Arrangement.spacedBy(8.dp)
+ ) {
+ message.reactions?.forEach { reaction ->
+ Reaction(reaction.key, reaction.value,
+ onClick = { hasOwn ->
+ scope.launch {
+ if (hasOwn) {
+ unreact(
+ message.channel!!,
+ message.id!!,
+ reaction.key
+ )
+ } else {
+ react(
+ message.channel!!,
+ message.id!!,
+ reaction.key
+ )
+ }
+ }
+ }
+ ) {
+ scope.launch {
+ ActionChannel.send(
+ Action.MessageReactionInfo(
+ message.id!!,
+ reaction.key
+ )
+ )
+ }
+ }
+ }
+
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .clip(MaterialTheme.shapes.small)
+ .background(
+ MaterialTheme.colorScheme.surfaceColorAtElevation(
+ 2.dp
+ )
+ )
+ .clickable(onClick = onAddReaction)
+ .padding(8.dp)
+ ) {
+ Icon(
+ painter = painterResource(R.drawable.ic_hamburger_plus_24dp),
+ contentDescription = stringResource(R.string.message_context_sheet_actions_react),
+ modifier = Modifier.size(16.dp)
+ )
+ }
+ }
+ Spacer(modifier = Modifier.height(8.dp))
+ }
}
}
}
diff --git a/app/src/main/res/drawable/ic_close_octagon_24dp.xml b/app/src/main/res/drawable/ic_close_octagon_24dp.xml
new file mode 100644
index 00000000..fceb5602
--- /dev/null
+++ b/app/src/main/res/drawable/ic_close_octagon_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 dffd60eb..ecd7c776 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -187,6 +187,8 @@
Unknown message
Sent attachments
+ Blocked message
+
Ownership changed
Channel icon changed
Channel description changed