feat: mention user on username tap
Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
parent
9e3543be37
commit
ae87815dca
|
|
@ -0,0 +1,22 @@
|
||||||
|
package chat.revolt.api.internals
|
||||||
|
|
||||||
|
import chat.revolt.api.RevoltAPI
|
||||||
|
|
||||||
|
object MessageProcessor {
|
||||||
|
private val MentionRegex = Regex("@((?:\\p{L}|[\\d_.-])+)#([0-9]{4})", RegexOption.IGNORE_CASE)
|
||||||
|
|
||||||
|
fun processOutgoing(content: String): String {
|
||||||
|
val mentions = MentionRegex.findAll(content).map { it.value }.toList()
|
||||||
|
|
||||||
|
return mentions.fold(content) { acc, mention ->
|
||||||
|
val (username, discriminator) = MentionRegex.matchEntire(mention)?.destructured
|
||||||
|
?: return@fold acc
|
||||||
|
|
||||||
|
val user =
|
||||||
|
RevoltAPI.userCache.values.find { it.username == username && it.discriminator == discriminator }
|
||||||
|
|
||||||
|
val userId = user?.id ?: return@fold acc
|
||||||
|
acc.replace(mention, "<@$userId>")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -64,11 +64,11 @@ import chat.revolt.api.internals.WebCompat
|
||||||
import chat.revolt.api.internals.solidColor
|
import chat.revolt.api.internals.solidColor
|
||||||
import chat.revolt.api.routes.microservices.january.asJanuaryProxyUrl
|
import chat.revolt.api.routes.microservices.january.asJanuaryProxyUrl
|
||||||
import chat.revolt.api.schemas.AutumnResource
|
import chat.revolt.api.schemas.AutumnResource
|
||||||
import chat.revolt.api.schemas.Message as MessageSchema
|
|
||||||
import chat.revolt.api.schemas.User
|
import chat.revolt.api.schemas.User
|
||||||
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.internals.markdown.LongClickableSpan
|
import chat.revolt.internals.markdown.LongClickableSpan
|
||||||
|
import chat.revolt.api.schemas.Message as MessageSchema
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun authorColour(message: MessageSchema): Brush {
|
fun authorColour(message: MessageSchema): Brush {
|
||||||
|
|
@ -163,6 +163,7 @@ fun Message(
|
||||||
parse: (MessageSchema) -> SpannableStringBuilder = { SpannableStringBuilder(it.content) },
|
parse: (MessageSchema) -> SpannableStringBuilder = { SpannableStringBuilder(it.content) },
|
||||||
onMessageContextMenu: () -> Unit = {},
|
onMessageContextMenu: () -> Unit = {},
|
||||||
onAvatarClick: () -> Unit = {},
|
onAvatarClick: () -> Unit = {},
|
||||||
|
onNameClick: (() -> Unit)? = null,
|
||||||
canReply: Boolean = false,
|
canReply: Boolean = false,
|
||||||
onReply: () -> Unit = {}
|
onReply: () -> Unit = {}
|
||||||
) {
|
) {
|
||||||
|
|
@ -252,7 +253,17 @@ fun Message(
|
||||||
brush = authorColour(message)
|
brush = authorColour(message)
|
||||||
),
|
),
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier.then(
|
||||||
|
if (onNameClick != null)
|
||||||
|
Modifier.combinedClickable(
|
||||||
|
onClick = onNameClick,
|
||||||
|
onLongClick = {
|
||||||
|
onMessageContextMenu()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else Modifier
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
InlineBadges(
|
InlineBadges(
|
||||||
|
|
|
||||||
|
|
@ -347,6 +347,11 @@ fun ChannelScreen(
|
||||||
onUserSheetOpenFor(author, channel?.server)
|
onUserSheetOpenFor(author, channel?.server)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onNameClick = {
|
||||||
|
val author = message.author?.let { RevoltAPI.userCache[it] }
|
||||||
|
?: return@Message
|
||||||
|
viewModel.putAtCursorPosition("@${author.username}#${author.discriminator}")
|
||||||
|
},
|
||||||
canReply = true,
|
canReply = true,
|
||||||
onReply = {
|
onReply = {
|
||||||
if (viewModel.pendingReplies.size >= 5) {
|
if (viewModel.pendingReplies.size >= 5) {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import chat.revolt.R
|
||||||
import chat.revolt.api.RevoltAPI
|
import chat.revolt.api.RevoltAPI
|
||||||
import chat.revolt.api.RevoltJson
|
import chat.revolt.api.RevoltJson
|
||||||
import chat.revolt.api.internals.ChannelUtils
|
import chat.revolt.api.internals.ChannelUtils
|
||||||
|
import chat.revolt.api.internals.MessageProcessor
|
||||||
import chat.revolt.api.internals.PermissionBit
|
import chat.revolt.api.internals.PermissionBit
|
||||||
import chat.revolt.api.internals.Roles
|
import chat.revolt.api.internals.Roles
|
||||||
import chat.revolt.api.internals.SpecialUsers
|
import chat.revolt.api.internals.SpecialUsers
|
||||||
|
|
@ -211,7 +212,7 @@ class ChannelScreenViewModel : ViewModel() {
|
||||||
|
|
||||||
sendMessage(
|
sendMessage(
|
||||||
activeChannel!!.id!!,
|
activeChannel!!.id!!,
|
||||||
pendingMessageContent.trimIndent(),
|
MessageProcessor.processOutgoing(pendingMessageContent.trimIndent()),
|
||||||
attachments = if (attachmentIds.isEmpty()) null else attachmentIds,
|
attachments = if (attachmentIds.isEmpty()) null else attachmentIds,
|
||||||
replies = pendingReplies
|
replies = pendingReplies
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue