feat: display role icons
This commit is contained in:
parent
55dbb2a8e5
commit
126011a3e3
|
|
@ -13,12 +13,12 @@ import androidx.compose.material3.LocalContentColor
|
|||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
|
|
@ -28,9 +28,12 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.compose.ui.unit.sp
|
||||
import chat.stoat.R
|
||||
import chat.stoat.api.StoatAPI
|
||||
import chat.stoat.api.internals.SpecialUsers
|
||||
import chat.stoat.api.internals.solidColor
|
||||
import chat.stoat.api.routes.channel.fetchSingleMessage
|
||||
import chat.stoat.composables.generic.RemoteImage
|
||||
import chat.stoat.composables.generic.UserAvatar
|
||||
import chat.stoat.core.model.data.STOAT_FILES
|
||||
import chat.stoat.core.model.schemas.User
|
||||
import java.util.concurrent.CancellationException
|
||||
|
||||
|
|
@ -52,6 +55,7 @@ fun InReplyTo(
|
|||
val contentColor = LocalContentColor.current
|
||||
val usernameColor =
|
||||
message?.let { authorColour(it) } ?: Brush.solidColor(contentColor)
|
||||
val roleIcon = message?.let { authorRoleIcon(it) }
|
||||
|
||||
val serverId = remember(channelId) { StoatAPI.channelCache[channelId]?.server }
|
||||
|
||||
|
|
@ -107,11 +111,26 @@ fun InReplyTo(
|
|||
modifier = Modifier.padding(horizontal = 4.dp)
|
||||
)
|
||||
|
||||
if (roleIcon != null) {
|
||||
RemoteImage(
|
||||
url = "$STOAT_FILES/icons/${roleIcon.id}",
|
||||
contentScale = ContentScale.Fit,
|
||||
description = null,
|
||||
modifier = Modifier
|
||||
.size(12.dp)
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
}
|
||||
|
||||
InlineBadges(
|
||||
bot = message.masquerade == null && author?.bot != null,
|
||||
bridge = message.masquerade != null && author?.bot != null,
|
||||
platformModeration = author?.id == SpecialUsers.PLATFORM_MODERATION_USER,
|
||||
teamMember = author?.id in SpecialUsers.TEAM_MEMBER_FLAIRS.keys,
|
||||
webhook = message.webhook != null,
|
||||
colour = contentColor.copy(alpha = 0.5f),
|
||||
modifier = Modifier.size(8.dp),
|
||||
modifier = Modifier.size(12.dp),
|
||||
followingIfAny = {
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import android.content.Intent
|
|||
import android.icu.text.DateFormat
|
||||
import android.net.Uri
|
||||
import android.text.format.DateUtils
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
|
|
@ -111,6 +110,17 @@ fun authorColour(message: MessageSchema): Brush {
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun authorRoleIcon(message: MessageSchema): AutumnResource? {
|
||||
val serverId = StoatAPI.channelCache[message.channel]?.server ?: return null
|
||||
|
||||
val highestRole = message.author?.let {
|
||||
Roles.resolveHighestRole(serverId, it)
|
||||
} ?: return null
|
||||
|
||||
return highestRole.icon
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun displayNameInChannel(userId: String, channelId: String): String {
|
||||
val serverId =
|
||||
|
|
@ -321,9 +331,6 @@ fun Message(
|
|||
} == true),
|
||||
) {
|
||||
// TODO Add jump to message
|
||||
if (replyMessage == null) {
|
||||
Toast.makeText(context, "lmao prankd", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -399,6 +406,19 @@ fun Message(
|
|||
)
|
||||
)
|
||||
|
||||
val roleIcon = authorRoleIcon(message)
|
||||
if (roleIcon != null) {
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
|
||||
RemoteImage(
|
||||
url = "$STOAT_FILES/icons/${roleIcon.id}",
|
||||
contentScale = ContentScale.Fit,
|
||||
description = null,
|
||||
modifier = Modifier
|
||||
.size(16.dp)
|
||||
)
|
||||
}
|
||||
|
||||
InlineBadges(
|
||||
bot = author.bot != null && message.masquerade == null,
|
||||
bridge = message.masquerade != null && author.bot != null,
|
||||
|
|
@ -520,7 +540,10 @@ fun Message(
|
|||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Embed(embed = embed, serverId = StoatAPI.channelCache[message.channel]?.server, onLinkClick = {
|
||||
Embed(
|
||||
embed = embed,
|
||||
serverId = StoatAPI.channelCache[message.channel]?.server,
|
||||
onLinkClick = {
|
||||
viewUrlInBrowser(context, it)
|
||||
})
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package chat.stoat.composables.generic
|
|||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
|
|
@ -39,9 +40,14 @@ fun ListHeader(
|
|||
fun CountableListHeader(
|
||||
text: String,
|
||||
count: Int,
|
||||
icon: @Composable (() -> Unit)? = null,
|
||||
backgroundColor: Color = MaterialTheme.colorScheme.surface
|
||||
) {
|
||||
ListHeader(backgroundColor = backgroundColor) {
|
||||
Row {
|
||||
if (icon != null) {
|
||||
icon()
|
||||
}
|
||||
Text(
|
||||
text = AnnotatedString.Builder().apply {
|
||||
append(text)
|
||||
|
|
@ -59,3 +65,4 @@ fun CountableListHeader(
|
|||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.Spacer
|
|||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
|
|
@ -28,6 +29,7 @@ import androidx.compose.runtime.setValue
|
|||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
|
@ -42,8 +44,11 @@ import chat.stoat.api.routes.server.fetchMembers
|
|||
import chat.stoat.composables.chat.MemberListItem
|
||||
import chat.stoat.composables.generic.CountableListHeader
|
||||
import chat.stoat.composables.generic.Presence
|
||||
import chat.stoat.composables.generic.RemoteImage
|
||||
import chat.stoat.composables.generic.SheetHeaderPadding
|
||||
import chat.stoat.composables.generic.presenceFromStatus
|
||||
import chat.stoat.core.model.data.STOAT_FILES
|
||||
import chat.stoat.core.model.schemas.AutumnResource
|
||||
import chat.stoat.core.model.schemas.Member
|
||||
import chat.stoat.core.model.schemas.User
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
|
|
@ -57,7 +62,11 @@ val DO_NOT_FETCH_OFFLINE_MEMBERS_SERVERS = listOf(
|
|||
sealed class MemberListSheetItem {
|
||||
data class MemberItem(val member: Member) : MemberListSheetItem()
|
||||
data class UserItem(val user: User) : MemberListSheetItem()
|
||||
data class CategoryItem(val category: String, val count: Int) : MemberListSheetItem()
|
||||
data class CategoryItem(
|
||||
val category: String,
|
||||
val count: Int,
|
||||
val icon: AutumnResource? = null
|
||||
) : MemberListSheetItem()
|
||||
}
|
||||
|
||||
class MemberListSheetViewModel(
|
||||
|
|
@ -116,7 +125,13 @@ class MemberListSheetViewModel(
|
|||
// Hoisted roles
|
||||
Roles.inOrder(serverId) { it.hoist == true }.forEach { role ->
|
||||
val members = categories[role.name] ?: return@forEach
|
||||
fullItemList.add(MemberListSheetItem.CategoryItem(role.name ?: "", members.size))
|
||||
fullItemList.add(
|
||||
MemberListSheetItem.CategoryItem(
|
||||
role.name ?: "",
|
||||
members.size,
|
||||
role.icon
|
||||
)
|
||||
)
|
||||
members.forEach { member ->
|
||||
fullItemList.add(MemberListSheetItem.MemberItem(member))
|
||||
}
|
||||
|
|
@ -312,6 +327,17 @@ fun MemberListSheet(
|
|||
CountableListHeader(
|
||||
text = item.category,
|
||||
count = item.count,
|
||||
icon = {
|
||||
if (item.icon == null) return@CountableListHeader
|
||||
RemoteImage(
|
||||
url = "$STOAT_FILES/icons/${item.icon.id}",
|
||||
contentScale = ContentScale.Fit,
|
||||
description = null,
|
||||
modifier = Modifier
|
||||
.padding(end = 8.dp)
|
||||
.size(16.dp)
|
||||
)
|
||||
},
|
||||
backgroundColor = MaterialTheme.colorScheme.surfaceContainerLow
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,8 @@ data class Role(
|
|||
val permissions: PermissionDescription? = null,
|
||||
val colour: String? = null,
|
||||
val hoist: Boolean? = null,
|
||||
val rank: Double? = null
|
||||
val rank: Double? = null,
|
||||
val icon: AutumnResource? = null
|
||||
) {
|
||||
fun mergeWithPartial(other: Role): Role {
|
||||
return Role(
|
||||
|
|
|
|||
Loading…
Reference in New Issue