feat: support discriminators
Signed-off-by: Infi <wingit@geist.ga>
This commit is contained in:
parent
9508416d88
commit
d3b6efa9fd
|
|
@ -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? {
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue