feat: support discriminators

Signed-off-by: Infi <wingit@geist.ga>
This commit is contained in:
Infi 2023-06-12 00:17:17 +02:00
parent 9508416d88
commit d3b6efa9fd
9 changed files with 95 additions and 32 deletions

View File

@ -2,11 +2,16 @@ package chat.revolt.api.internals
import chat.revolt.api.RevoltAPI
import chat.revolt.api.schemas.Channel
import chat.revolt.api.schemas.User
object ChannelUtils {
fun resolveDMName(channel: Channel): String? {
return channel.name
?: RevoltAPI.userCache[channel.recipients?.first { u -> u != RevoltAPI.selfId }]?.username
?: RevoltAPI.userCache[channel.recipients?.first { u -> u != RevoltAPI.selfId }]?.let {
User.resolveDefaultName(
it
)
}
}
fun resolveDMPartner(channel: Channel): String? {

View File

@ -1,15 +1,16 @@
package chat.revolt.api.schemas
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
import kotlinx.serialization.json.*
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class User(
@SerialName("_id")
val id: String? = null,
val username: String? = null,
val discriminator: String? = null,
@SerialName("display_name")
val displayName: String? = null,
val avatar: AutumnResource? = null,
val relations: List<Relation>? = null,
val badges: Long? = null,
@ -25,6 +26,8 @@ data class User(
return User(
id = partial.id ?: id,
username = partial.username ?: username,
discriminator = partial.discriminator ?: discriminator,
displayName = partial.displayName ?: displayName,
avatar = partial.avatar ?: avatar,
relations = partial.relations ?: relations,
badges = partial.badges ?: badges,
@ -42,6 +45,8 @@ data class User(
fun getPlaceholder(forId: String) = User(
id = forId,
username = "Unknown User",
discriminator = "0000",
displayName = null,
avatar = null,
badges = 0,
status = null,
@ -52,6 +57,11 @@ data class User(
relationship = null,
online = false
)
fun resolveDefaultName(user: User, withDiscriminator: Boolean = false): String {
val maybeDiscriminator = if (withDiscriminator) "#${user.discriminator}" else ""
return user.displayName ?: "${user.username}$maybeDiscriminator"
}
}
}

View File

@ -22,8 +22,8 @@ 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.internals.WebCompat
import chat.revolt.api.routes.microservices.january.asJanuaryProxyUrl
import chat.revolt.api.schemas.User
import chat.revolt.components.generic.UserAvatar
@Composable
@ -36,12 +36,12 @@ fun InReplyTo(
val message = RevoltAPI.messageCache[messageId]
val author = RevoltAPI.userCache[message?.author ?: ""]
val username = message?.masquerade?.name ?: author?.username ?: ""
val username = message?.let { authorName(it) }
?: author?.let { User.resolveDefaultName(it) }
?: stringResource(id = R.string.unknown)
val contentColor = LocalContentColor.current
val usernameColor = message?.masquerade?.colour?.let {
WebCompat.parseColour(it)
} ?: contentColor
val usernameColor = message?.let { authorColour(it) } ?: contentColor
Box(
modifier = modifier

View File

@ -52,6 +52,7 @@ import chat.revolt.api.internals.ULID
import chat.revolt.api.internals.WebCompat
import chat.revolt.api.routes.microservices.january.asJanuaryProxyUrl
import chat.revolt.api.schemas.AutumnResource
import chat.revolt.api.schemas.User
import chat.revolt.components.generic.UserAvatar
import chat.revolt.components.generic.UserAvatarWidthPlaceholder
import chat.revolt.api.schemas.Message as MessageSchema
@ -67,11 +68,9 @@ fun authorColour(message: MessageSchema): Color {
@Composable
fun authorName(message: MessageSchema): String {
return if (message.masquerade?.name != null) {
message.masquerade.name
} else {
RevoltAPI.userCache[message.author]?.username ?: stringResource(id = R.string.unknown)
}
return message.masquerade?.name
?: RevoltAPI.userCache[message.author]?.let { User.resolveDefaultName(it) }
?: stringResource(R.string.unknown)
}
fun viewUrlInBrowser(ctx: android.content.Context, url: String) {
@ -194,7 +193,7 @@ fun Message(
Column {
Spacer(modifier = Modifier.height(4.dp))
UserAvatar(
username = author.username ?: "",
username = User.resolveDefaultName(author),
userId = author.id ?: message.id ?: ULID.makeSpecial(0),
avatar = author.avatar,
rawUrl = message.masquerade?.avatar?.let { asJanuaryProxyUrl(it) }

View File

@ -14,7 +14,6 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Icon
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.surfaceColorAtElevation
@ -29,10 +28,12 @@ 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.internals.WebCompat
import chat.revolt.api.internals.ULID
import chat.revolt.api.routes.channel.SendMessageReply
import chat.revolt.api.routes.microservices.january.asJanuaryProxyUrl
import chat.revolt.api.schemas.Message
import chat.revolt.components.chat.authorColour
import chat.revolt.components.chat.authorName
import chat.revolt.components.generic.UserAvatar
@Composable
@ -76,8 +77,8 @@ fun ManageableReply(
Spacer(modifier = Modifier.width(8.dp))
UserAvatar(
username = replyAuthor.username!!,
userId = replyAuthor.id!!,
username = authorName(message = replyMessage),
userId = replyAuthor.id ?: ULID.makeSpecial(0),
avatar = replyAuthor.avatar,
rawUrl = replyMessage.masquerade?.avatar?.let { asJanuaryProxyUrl(it) },
size = 16.dp
@ -86,16 +87,14 @@ fun ManageableReply(
Spacer(modifier = Modifier.width(4.dp))
Text(
text = replyMessage.masquerade?.name ?: replyAuthor.username,
text = authorName(message = replyMessage),
fontSize = 12.sp,
modifier = Modifier
.clickable {
onToggleMention()
}
.padding(4.dp),
color = if (replyMessage.masquerade?.colour != null) {
WebCompat.parseColour(replyMessage.masquerade.colour)
} else LocalContentColor.current,
color = authorColour(message = replyMessage),
fontWeight = FontWeight.Bold,
)

View File

@ -1,8 +1,17 @@
package chat.revolt.components.screens.chat
import androidx.compose.animation.*
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@ -17,6 +26,7 @@ import chat.revolt.R
import chat.revolt.activities.RevoltTweenFloat
import chat.revolt.activities.RevoltTweenInt
import chat.revolt.api.RevoltAPI
import chat.revolt.api.schemas.User
import chat.revolt.components.generic.UserAvatar
@Composable
@ -33,7 +43,7 @@ fun StackedUserAvatars(
UserAvatar(
avatar = user?.avatar,
userId = userId,
username = user?.username ?: stringResource(id = R.string.unknown),
username = user?.let {User.resolveDefaultName(it)} ?: stringResource(id = R.string.unknown),
size = 16.dp,
modifier = Modifier
.offset(
@ -87,7 +97,7 @@ fun TypingIndicator(
id = typingMessageResource(),
users.joinToString {
RevoltAPI.userCache[it]?.let { u ->
u.username ?: u.id
User.resolveDefaultName(u)
} ?: it
}
),

View File

@ -31,6 +31,7 @@ import chat.revolt.R
import chat.revolt.api.RevoltAPI
import chat.revolt.api.internals.ChannelUtils
import chat.revolt.api.schemas.ChannelType
import chat.revolt.api.schemas.User
import chat.revolt.components.generic.presenceFromStatus
import chat.revolt.components.screens.chat.drawer.server.DrawerChannel
import chat.revolt.sheets.ChannelContextSheet
@ -157,7 +158,7 @@ fun RowScope.ChannelList(
)] else null
DrawerChannel(
name = partner?.username ?: channel.name
name = partner?.let { p -> User.resolveDefaultName(p) } ?: channel.name
?: stringResource(R.string.unknown),
channelType = channel.channelType ?: ChannelType.TextChannel,
selected = currentDestination == "channel/{channelId}" && currentChannel == channel.id,
@ -169,7 +170,7 @@ fun RowScope.ChannelList(
} ?: false,
dmPartnerIcon = partner?.avatar ?: channel.icon,
dmPartnerId = partner?.id,
dmPartnerName = partner?.username,
dmPartnerName = partner?.let { p -> User.resolveDefaultName(p) },
dmPartnerStatus = presenceFromStatus(
partner?.status?.presence ?: "Offline"
),

View File

@ -54,6 +54,7 @@ import chat.revolt.R
import chat.revolt.api.RevoltAPI
import chat.revolt.api.realtime.DisconnectionState
import chat.revolt.api.realtime.RealtimeSocket
import chat.revolt.api.schemas.User
import chat.revolt.api.settings.SyncedSettings
import chat.revolt.components.chat.DisconnectedNotice
import chat.revolt.components.generic.UserAvatar
@ -332,7 +333,11 @@ fun ChatRouterScreen(topNav: NavController, viewModel: ChatRouterViewModel = hil
horizontalAlignment = Alignment.CenterHorizontally
) {
UserAvatar(
username = RevoltAPI.userCache[RevoltAPI.selfId]?.username
username = RevoltAPI.userCache[RevoltAPI.selfId]?.let {
User.resolveDefaultName(
it
)
}
?: "",
presence = presenceFromStatus(
RevoltAPI.userCache[RevoltAPI.selfId]?.status?.presence

View File

@ -1,9 +1,11 @@
package chat.revolt.sheets
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
@ -11,12 +13,19 @@ import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import chat.revolt.R
import chat.revolt.api.RevoltAPI
import chat.revolt.api.internals.ULID
import chat.revolt.components.generic.SheetClickable
import chat.revolt.components.generic.UserAvatar
import chat.revolt.components.generic.presenceFromStatus
@Composable
fun StatusSheet(
@ -30,7 +39,32 @@ fun StatusSheet(
.padding(horizontal = 16.dp, vertical = 8.dp)
.verticalScroll(rememberScrollState())
) {
Text(text = "Logged in as @${selfUser.username} (${selfUser.id})")
Row(
verticalAlignment = Alignment.CenterVertically
) {
UserAvatar(
username = selfUser.displayName ?: stringResource(id = R.string.unknown),
userId = selfUser.id ?: ULID.makeSpecial(0),
avatar = selfUser.avatar,
size = 48.dp,
presence = presenceFromStatus(selfUser.status?.presence ?: "offline"),
)
Spacer(modifier = Modifier.width(12.dp))
Text(text = AnnotatedString.Builder().apply {
if (selfUser.displayName != null) {
pushStyle(SpanStyle(fontWeight = FontWeight.Bold))
append(selfUser.displayName)
pop()
append("\n")
}
append("${selfUser.username}")
pushStyle(SpanStyle(fontWeight = FontWeight.ExtraLight))
append("#${selfUser.discriminator}")
pop()
}.toAnnotatedString())
}
Spacer(modifier = Modifier.height(8.dp))