feat: tiny ux tweaks

This commit is contained in:
Infi 2023-03-04 01:16:35 +01:00
parent 74a1454f73
commit 96fb9f8983
8 changed files with 105 additions and 77 deletions

View File

@ -50,11 +50,7 @@ class Unreads {
suspend fun markAsRead(channelId: String, messageId: String, sync: Boolean = true) { suspend fun markAsRead(channelId: String, messageId: String, sync: Boolean = true) {
if (!hasLoaded.value) return if (!hasLoaded.value) return
channels[channelId]?.let { channels[channelId]?.let {
if (it.last_id == messageId) { channels[channelId] = it.copy(last_id = messageId)
channels.remove(channelId)
} else {
channels[channelId] = it.copy(last_id = messageId)
}
} }
if (sync) { if (sync) {
ackChannel(channelId, messageId) ackChannel(channelId, messageId)
@ -63,11 +59,7 @@ class Unreads {
fun processExternalAck(channelId: String, messageId: String) { fun processExternalAck(channelId: String, messageId: String) {
channels[channelId]?.let { channels[channelId]?.let {
if (it.last_id == messageId) { channels[channelId] = it.copy(last_id = messageId)
channels.remove(channelId)
} else {
channels[channelId] = it.copy(last_id = messageId)
}
} }
} }

View File

@ -2,12 +2,13 @@ package chat.revolt.components.chat
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
@ -16,6 +17,7 @@ import androidx.compose.ui.unit.sp
import chat.revolt.R import chat.revolt.R
import chat.revolt.api.RevoltAPI import chat.revolt.api.RevoltAPI
import chat.revolt.api.asJanuaryProxyUrl import chat.revolt.api.asJanuaryProxyUrl
import chat.revolt.api.internals.WebCompat
import chat.revolt.components.generic.UserAvatar import chat.revolt.components.generic.UserAvatar
@Composable @Composable
@ -30,67 +32,77 @@ fun InReplyTo(
val username = message?.masquerade?.name ?: author?.username ?: "" val username = message?.masquerade?.name ?: author?.username ?: ""
Row( val contentColor = LocalContentColor.current
val usernameColor = message?.masquerade?.colour?.let {
WebCompat.parseColour(it)
} ?: contentColor
Box(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.padding(4.dp) .clickable { onMessageClick(messageId) }
.clickable { onMessageClick(messageId) },
verticalAlignment = Alignment.CenterVertically,
) { ) {
Spacer(modifier = Modifier.width(48.dp)) Row(
modifier = Modifier.padding(4.dp),
verticalAlignment = Alignment.CenterVertically
) {
Spacer(modifier = Modifier.width(40.dp))
if (message != null) { if (message != null) {
UserAvatar( UserAvatar(
username = username, username = username,
userId = author?.id ?: "", userId = author?.id ?: "",
avatar = author?.avatar, avatar = author?.avatar,
rawUrl = message.masquerade?.avatar?.let { asJanuaryProxyUrl(it) }, rawUrl = message.masquerade?.avatar?.let { asJanuaryProxyUrl(it) },
size = 16.dp size = 16.dp
) )
Text( Text(
text = if (author != null) { text = if (author != null) {
if (withMention) { if (withMention) {
"@$username" "@$username"
} else {
username
}
} else { } else {
username stringResource(id = R.string.unknown)
},
fontWeight = FontWeight.Bold,
fontSize = 12.sp,
color = usernameColor,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(horizontal = 4.dp)
)
InlineBadges(
bot = message.masquerade == null && author?.bot != null,
masquerade = message.masquerade != null && author?.bot != null,
colour = contentColor.copy(alpha = 0.5f),
modifier = Modifier.size(8.dp),
followingIfAny = {
Spacer(modifier = Modifier.width(4.dp))
} }
} else { )
stringResource(id = R.string.unknown)
},
fontWeight = FontWeight.Bold,
fontSize = 12.sp,
color = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.9f),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(horizontal = 4.dp)
)
InlineBadges( Text(
bot = message.masquerade == null && author?.bot != null, text = message.content ?: "",
masquerade = message.masquerade != null && author?.bot != null, fontSize = 12.sp,
colour = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.5f), color = contentColor.copy(alpha = 0.7f),
modifier = Modifier.size(8.dp), maxLines = 1,
followingIfAny = { overflow = TextOverflow.Ellipsis
Spacer(modifier = Modifier.width(4.dp)) )
} } else {
) Text(
text = stringResource(id = R.string.reply_message_not_cached),
Text( fontStyle = FontStyle.Italic, // inter doesn't have italics...
text = message.content ?: "", color = contentColor.copy(alpha = 0.7f),
fontSize = 12.sp, fontFamily = FontFamily.Default, // ...so we use the defaul t font
color = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.7f), fontSize = 12.sp,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
} else { }
Text(
text = stringResource(id = R.string.reply_message_not_cached),
fontStyle = FontStyle.Italic,
fontSize = 14.sp,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
} }
} }
} }

View File

@ -1,6 +1,7 @@
package chat.revolt.components.chat package chat.revolt.components.chat
import android.net.Uri import android.net.Uri
import android.widget.Toast
import androidx.browser.customtabs.CustomTabsIntent import androidx.browser.customtabs.CustomTabsIntent
import androidx.compose.foundation.* import androidx.compose.foundation.*
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
@ -24,7 +25,7 @@ import chat.revolt.api.schemas.AutumnResource
import chat.revolt.components.generic.RemoteImage import chat.revolt.components.generic.RemoteImage
import chat.revolt.components.generic.UserAvatar import chat.revolt.components.generic.UserAvatar
import chat.revolt.components.generic.UserAvatarWidthPlaceholder import chat.revolt.components.generic.UserAvatarWidthPlaceholder
import chat.revolt.markdown.Renderer import chat.revolt.markdown.Markdown
import chat.revolt.api.schemas.Message as MessageSchema import chat.revolt.api.schemas.Message as MessageSchema
fun viewAttachmentInBrowser(ctx: android.content.Context, attachment: AutumnResource) { fun viewAttachmentInBrowser(ctx: android.content.Context, attachment: AutumnResource) {
@ -62,13 +63,17 @@ fun Message(
} }
message.replies?.forEach { reply -> message.replies?.forEach { reply ->
val replyMessage = RevoltAPI.messageCache[reply] ?: return@forEach val replyMessage = RevoltAPI.messageCache[reply]
InReplyTo( InReplyTo(
messageId = reply, messageId = reply,
withMention = message.mentions?.contains(replyMessage.author) == true withMention = replyMessage?.author?.let { message.mentions?.contains(replyMessage.author) }
?: false,
) { ) {
// TODO Add jump to message // TODO Add jump to message
if (replyMessage == null) {
Toast.makeText(context, "lmao prankd", Toast.LENGTH_SHORT).show()
}
} }
} }
@ -131,7 +136,7 @@ fun Message(
message.content?.let { message.content?.let {
Text( Text(
text = Renderer.annotateMarkdown(it), text = Markdown.annotate(it),
maxLines = if (truncate) 1 else Int.MAX_VALUE, maxLines = if (truncate) 1 else Int.MAX_VALUE,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )

View File

@ -0,0 +1,11 @@
package chat.revolt.internals.markdown
import androidx.compose.runtime.snapshots.SnapshotStateMap
import chat.revolt.api.schemas.User
data class MarkdownContext(
val memberMap: SnapshotStateMap<String, String>,
val userMap: SnapshotStateMap<String, User>,
val channelMap: SnapshotStateMap<String, String>,
val serverId: String,
)

View File

@ -27,6 +27,7 @@ import chat.revolt.api.routes.user.blockUser
import chat.revolt.api.schemas.ContentReportReason import chat.revolt.api.schemas.ContentReportReason
import chat.revolt.components.chat.Message import chat.revolt.components.chat.Message
import chat.revolt.components.generic.FormTextField import chat.revolt.components.generic.FormTextField
import chat.revolt.markdown.Markdown
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
enum class ReportingState { enum class ReportingState {
@ -48,6 +49,9 @@ fun ReportMessageDialog(
return return
} }
val author = RevoltAPI.userCache[message.author]
val messageIsBridged = author?.let { author.bot != null && message.masquerade != null } ?: false
val state = remember { mutableStateOf(ReportingState.Reason) } val state = remember { mutableStateOf(ReportingState.Reason) }
val selectedReason = remember { mutableStateOf("Illegal") } val selectedReason = remember { mutableStateOf("Illegal") }
@ -104,6 +108,14 @@ fun ReportMessageDialog(
) )
} }
if (messageIsBridged) {
Spacer(modifier = Modifier.height(8.dp))
Text(
text = Markdown.annotate(stringResource(id = R.string.report_message_bridge_notice)),
fontSize = 12.sp
)
}
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
Box { Box {

View File

@ -155,6 +155,7 @@
<string name="report_message">Thank you for taking the time to report this message. Please provide a reason for reporting this message.</string> <string name="report_message">Thank you for taking the time to report this message. Please provide a reason for reporting this message.</string>
<string name="report_message_preview">Selected message:</string> <string name="report_message_preview">Selected message:</string>
<string name="report_message_bridge_notice">**Note:** This message may have been sent from another platform. It is recommended to also report the message on the platform it was sent from.</string>
<string name="report_server">Thank you for taking the time to report this server. Please provide a reason for reporting this server.</string> <string name="report_server">Thank you for taking the time to report this server. Please provide a reason for reporting this server.</string>
<string name="report_server_preview">Selected server:</string> <string name="report_server_preview">Selected server:</string>
<string name="report_user">Thank you for taking the time to report this user. Please provide a reason for reporting this user.</string> <string name="report_user">Thank you for taking the time to report this user. Please provide a reason for reporting this user.</string>

View File

@ -5,8 +5,8 @@ import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
object Renderer { object Markdown {
fun annotateMarkdown(text: String): AnnotatedString { fun <Ctx> annotateInContext(text: String, context: Ctx): AnnotatedString {
// TODO this is all placeholder code // TODO this is all placeholder code
val boldRegex = Regex("\\*\\*(.*?)\\*\\*") val boldRegex = Regex("\\*\\*(.*?)\\*\\*")
return buildAnnotatedString { return buildAnnotatedString {
@ -23,4 +23,6 @@ object Renderer {
toAnnotatedString() toAnnotatedString()
} }
} }
fun annotate(text: String): AnnotatedString = annotateInContext(text, Unit)
} }

View File

@ -58,10 +58,3 @@ open class Node(
*/ */
val position: Position = Position() val position: Position = Position()
) )
open class UnistParent(
/**
* List representing the children of a node.
*/
val children: List<Node> = emptyList()
) : Node()