feat: m3 list style
This commit is contained in:
parent
8c197165b3
commit
3a07d78da3
|
|
@ -1,22 +1,28 @@
|
||||||
package chat.stoat.composables.chat
|
package chat.stoat.composables.chat
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.material3.ListItem
|
import androidx.compose.material3.ListItem
|
||||||
|
import androidx.compose.material3.ListItemDefaults
|
||||||
import androidx.compose.material3.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Brush
|
import androidx.compose.ui.graphics.Brush
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import chat.stoat.api.internals.BrushCompat
|
import chat.stoat.api.internals.BrushCompat
|
||||||
import chat.stoat.api.internals.Roles
|
import chat.stoat.api.internals.Roles
|
||||||
import chat.stoat.api.internals.solidColor
|
import chat.stoat.api.internals.solidColor
|
||||||
import chat.stoat.core.model.schemas.Member
|
|
||||||
import chat.stoat.core.model.schemas.User
|
|
||||||
import chat.stoat.composables.generic.UserAvatar
|
import chat.stoat.composables.generic.UserAvatar
|
||||||
import chat.stoat.composables.generic.presenceFromStatus
|
import chat.stoat.composables.generic.presenceFromStatus
|
||||||
import chat.stoat.core.model.data.STOAT_FILES
|
import chat.stoat.core.model.data.STOAT_FILES
|
||||||
import chat.stoat.internals.extensions.TransparentListItemColours
|
import chat.stoat.core.model.schemas.Member
|
||||||
|
import chat.stoat.core.model.schemas.User
|
||||||
|
|
||||||
|
private val NoneLambda = { }
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MemberListItem(
|
fun MemberListItem(
|
||||||
|
|
@ -25,6 +31,10 @@ fun MemberListItem(
|
||||||
serverId: String?,
|
serverId: String?,
|
||||||
userId: String,
|
userId: String,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
first: Boolean = false,
|
||||||
|
last: Boolean = false,
|
||||||
|
onClick: () -> Unit = {},
|
||||||
|
onLongClick: () -> Unit = NoneLambda,
|
||||||
trailingContent: @Composable (() -> Unit)? = null,
|
trailingContent: @Composable (() -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
val highestColourRole = serverId?.let {
|
val highestColourRole = serverId?.let {
|
||||||
|
|
@ -41,8 +51,43 @@ fun MemberListItem(
|
||||||
?: Brush.solidColor(LocalContentColor.current)
|
?: Brush.solidColor(LocalContentColor.current)
|
||||||
|
|
||||||
ListItem(
|
ListItem(
|
||||||
colors = TransparentListItemColours,
|
colors = ListItemDefaults.colors(
|
||||||
modifier = modifier,
|
containerColor = MaterialTheme.colorScheme.surfaceContainer
|
||||||
|
),
|
||||||
|
modifier = modifier
|
||||||
|
.then(
|
||||||
|
when {
|
||||||
|
first && last -> Modifier.clip(MaterialTheme.shapes.large)
|
||||||
|
|
||||||
|
first -> Modifier.clip(
|
||||||
|
MaterialTheme.shapes.extraSmall.copy(
|
||||||
|
topStart = MaterialTheme.shapes.large.topStart,
|
||||||
|
topEnd = MaterialTheme.shapes.large.topEnd
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
last -> Modifier.clip(
|
||||||
|
MaterialTheme.shapes.extraSmall.copy(
|
||||||
|
bottomStart = MaterialTheme.shapes.large.bottomStart,
|
||||||
|
bottomEnd = MaterialTheme.shapes.large.bottomEnd
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
else -> Modifier.clip(MaterialTheme.shapes.extraSmall)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
if (onLongClick != NoneLambda) {
|
||||||
|
Modifier.combinedClickable(
|
||||||
|
onClick = onClick,
|
||||||
|
onLongClick = onLongClick
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Modifier.clickable(
|
||||||
|
onClick = onClick
|
||||||
|
)
|
||||||
|
}
|
||||||
|
),
|
||||||
headlineContent = {
|
headlineContent = {
|
||||||
Text(
|
Text(
|
||||||
text = member?.nickname
|
text = member?.nickname
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,6 @@ import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
val TransparentListItemColours: ListItemColors
|
val TransparentListItemColours: ListItemColors
|
||||||
@Composable
|
@Composable
|
||||||
get() = ListItemDefaults.colors().copy(
|
get() = ListItemDefaults.colors(
|
||||||
containerColor = Color.Transparent
|
containerColor = Color.Transparent
|
||||||
)
|
)
|
||||||
|
|
@ -7,7 +7,6 @@ import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -179,8 +178,24 @@ fun FriendsScreen(topNav: NavController, useDrawer: Boolean, onDrawerClicked: ()
|
||||||
text = AnnotatedString.fromHtml(
|
text = AnnotatedString.fromHtml(
|
||||||
stringResource(
|
stringResource(
|
||||||
R.string.friends_add_by_tag_sheet_description,
|
R.string.friends_add_by_tag_sheet_description,
|
||||||
"<font color=\"${Color(HL_USERNAME).toArgb().let { "#%02x%02x%02x".format(it shr 16 and 0xff, it shr 8 and 0xff, it and 0xff) }}\">",
|
"<font color=\"${
|
||||||
"<font color=\"${Color(HL_TAG).toArgb().let { "#%02x%02x%02x".format(it shr 16 and 0xff, it shr 8 and 0xff, it and 0xff) }}\">",
|
Color(HL_USERNAME).toArgb().let {
|
||||||
|
"#%02x%02x%02x".format(
|
||||||
|
it shr 16 and 0xff,
|
||||||
|
it shr 8 and 0xff,
|
||||||
|
it and 0xff
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}\">",
|
||||||
|
"<font color=\"${
|
||||||
|
Color(HL_TAG).toArgb().let {
|
||||||
|
"#%02x%02x%02x".format(
|
||||||
|
it shr 16 and 0xff,
|
||||||
|
it shr 8 and 0xff,
|
||||||
|
it and 0xff
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}\">",
|
||||||
"</font>",
|
"</font>",
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
@ -601,19 +616,28 @@ fun FriendsScreen(topNav: NavController, useDrawer: Boolean, onDrawerClicked: ()
|
||||||
val item = FriendRequests.getIncoming().getOrNull(it)
|
val item = FriendRequests.getIncoming().getOrNull(it)
|
||||||
if (item == null) return@items
|
if (item == null) return@items
|
||||||
|
|
||||||
|
val isLast = it == FriendRequests.getIncoming().size - 1
|
||||||
|
|
||||||
MemberListItem(
|
MemberListItem(
|
||||||
member = null,
|
member = null,
|
||||||
user = item,
|
user = item,
|
||||||
serverId = null,
|
serverId = null,
|
||||||
userId = item.id ?: "",
|
userId = item.id ?: "",
|
||||||
modifier = Modifier.clickable {
|
first = it == 0,
|
||||||
|
last = isLast,
|
||||||
|
onClick = {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
item.id?.let { userId ->
|
item.id?.let { userId ->
|
||||||
ActionChannel.send(Action.OpenUserSheet(userId, null))
|
ActionChannel.send(Action.OpenUserSheet(userId, null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (!isLast) {
|
||||||
|
Spacer(modifier = Modifier.height(2.dp))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stickyHeader(key = "outgoing") {
|
stickyHeader(key = "outgoing") {
|
||||||
|
|
@ -627,19 +651,28 @@ fun FriendsScreen(topNav: NavController, useDrawer: Boolean, onDrawerClicked: ()
|
||||||
val item = FriendRequests.getOutgoing().getOrNull(it)
|
val item = FriendRequests.getOutgoing().getOrNull(it)
|
||||||
if (item == null) return@items
|
if (item == null) return@items
|
||||||
|
|
||||||
|
val isLast = it == FriendRequests.getOutgoing().size - 1
|
||||||
|
|
||||||
MemberListItem(
|
MemberListItem(
|
||||||
member = null,
|
member = null,
|
||||||
user = item,
|
user = item,
|
||||||
serverId = null,
|
serverId = null,
|
||||||
userId = item.id ?: "",
|
userId = item.id ?: "",
|
||||||
modifier = Modifier.clickable {
|
first = it == 0,
|
||||||
|
last = isLast,
|
||||||
|
onClick = {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
item.id?.let { userId ->
|
item.id?.let { userId ->
|
||||||
ActionChannel.send(Action.OpenUserSheet(userId, null))
|
ActionChannel.send(Action.OpenUserSheet(userId, null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (!isLast) {
|
||||||
|
Spacer(modifier = Modifier.height(2.dp))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stickyHeader(key = "online") {
|
stickyHeader(key = "online") {
|
||||||
|
|
@ -653,19 +686,28 @@ fun FriendsScreen(topNav: NavController, useDrawer: Boolean, onDrawerClicked: ()
|
||||||
val item = FriendRequests.getOnlineFriends().getOrNull(it)
|
val item = FriendRequests.getOnlineFriends().getOrNull(it)
|
||||||
if (item == null) return@items
|
if (item == null) return@items
|
||||||
|
|
||||||
|
val isLast = it == FriendRequests.getOnlineFriends().size - 1
|
||||||
|
|
||||||
MemberListItem(
|
MemberListItem(
|
||||||
member = null,
|
member = null,
|
||||||
user = item,
|
user = item,
|
||||||
serverId = null,
|
serverId = null,
|
||||||
userId = item.id ?: "",
|
userId = item.id ?: "",
|
||||||
modifier = Modifier.clickable {
|
first = it == 0,
|
||||||
|
last = isLast,
|
||||||
|
onClick = {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
item.id?.let { userId ->
|
item.id?.let { userId ->
|
||||||
ActionChannel.send(Action.OpenUserSheet(userId, null))
|
ActionChannel.send(Action.OpenUserSheet(userId, null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (!isLast) {
|
||||||
|
Spacer(modifier = Modifier.height(2.dp))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stickyHeader(key = "not_online") {
|
stickyHeader(key = "not_online") {
|
||||||
|
|
@ -679,19 +721,28 @@ fun FriendsScreen(topNav: NavController, useDrawer: Boolean, onDrawerClicked: ()
|
||||||
val item = FriendRequests.getFriends(true).getOrNull(it)
|
val item = FriendRequests.getFriends(true).getOrNull(it)
|
||||||
if (item == null) return@items
|
if (item == null) return@items
|
||||||
|
|
||||||
|
val isLast = it == FriendRequests.getFriends(true).size - 1
|
||||||
|
|
||||||
MemberListItem(
|
MemberListItem(
|
||||||
member = null,
|
member = null,
|
||||||
user = item,
|
user = item,
|
||||||
serverId = null,
|
serverId = null,
|
||||||
userId = item.id ?: "",
|
userId = item.id ?: "",
|
||||||
modifier = Modifier.clickable {
|
first = it == 0,
|
||||||
|
last = isLast,
|
||||||
|
onClick = {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
item.id?.let { userId ->
|
item.id?.let { userId ->
|
||||||
ActionChannel.send(Action.OpenUserSheet(userId, null))
|
ActionChannel.send(Action.OpenUserSheet(userId, null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (!isLast) {
|
||||||
|
Spacer(modifier = Modifier.height(2.dp))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stickyHeader(key = "blocked") {
|
stickyHeader(key = "blocked") {
|
||||||
|
|
@ -706,19 +757,28 @@ fun FriendsScreen(topNav: NavController, useDrawer: Boolean, onDrawerClicked: ()
|
||||||
val item = FriendRequests.getBlocked().getOrNull(it)
|
val item = FriendRequests.getBlocked().getOrNull(it)
|
||||||
if (item == null) return@items
|
if (item == null) return@items
|
||||||
|
|
||||||
|
val isLast = it == FriendRequests.getBlocked().size - 1
|
||||||
|
|
||||||
MemberListItem(
|
MemberListItem(
|
||||||
member = null,
|
member = null,
|
||||||
user = item,
|
user = item,
|
||||||
serverId = null,
|
serverId = null,
|
||||||
userId = item.id ?: "",
|
userId = item.id ?: "",
|
||||||
modifier = Modifier.clickable {
|
first = it == 0,
|
||||||
|
last = isLast,
|
||||||
|
onClick = {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
item.id?.let { userId ->
|
item.id?.let { userId ->
|
||||||
ActionChannel.send(Action.OpenUserSheet(userId, null))
|
ActionChannel.send(Action.OpenUserSheet(userId, null))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (!isLast) {
|
||||||
|
Spacer(modifier = Modifier.height(2.dp))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,11 @@ package chat.stoat.screens.create
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.scaleIn
|
import androidx.compose.animation.scaleIn
|
||||||
import androidx.compose.animation.scaleOut
|
import androidx.compose.animation.scaleOut
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
|
@ -192,13 +193,16 @@ fun CreateGroupScreen(
|
||||||
val friend = StoatAPI.userCache[viewModel.friendsFilteredBySearch[index]]
|
val friend = StoatAPI.userCache[viewModel.friendsFilteredBySearch[index]]
|
||||||
?: return@items
|
?: return@items
|
||||||
val isMember = viewModel.groupMembers.contains(friend.id)
|
val isMember = viewModel.groupMembers.contains(friend.id)
|
||||||
|
val isLast = index == viewModel.friendsFilteredBySearch.size - 1
|
||||||
|
|
||||||
MemberListItem(
|
MemberListItem(
|
||||||
member = null,
|
member = null,
|
||||||
user = friend,
|
user = friend,
|
||||||
serverId = null,
|
serverId = null,
|
||||||
userId = friend.id!!,
|
userId = friend.id!!,
|
||||||
modifier = Modifier.clickable {
|
first = index == 0,
|
||||||
|
last = isLast,
|
||||||
|
onClick = {
|
||||||
if (isMember) {
|
if (isMember) {
|
||||||
viewModel.groupMembers.remove(friend.id)
|
viewModel.groupMembers.remove(friend.id)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -207,6 +211,7 @@ fun CreateGroupScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp),
|
||||||
trailingContent = {
|
trailingContent = {
|
||||||
Checkbox(
|
Checkbox(
|
||||||
checked = isMember,
|
checked = isMember,
|
||||||
|
|
@ -215,6 +220,9 @@ fun CreateGroupScreen(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
if (!isLast) {
|
||||||
|
Spacer(modifier = Modifier.height(2.dp))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import android.content.Intent
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
|
@ -13,6 +15,7 @@ import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.LargeTopAppBar
|
import androidx.compose.material3.LargeTopAppBar
|
||||||
import androidx.compose.material3.ListItem
|
import androidx.compose.material3.ListItem
|
||||||
|
import androidx.compose.material3.ListItemDefaults
|
||||||
import androidx.compose.material3.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
|
|
@ -21,6 +24,7 @@ import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
|
|
@ -100,18 +104,15 @@ fun SettingsScreen(
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(vertical = 10.dp)
|
.padding(bottom = 10.dp)
|
||||||
) {
|
) {
|
||||||
ListHeader {
|
ListHeader {
|
||||||
Text(stringResource(R.string.settings_category_account))
|
Text(stringResource(R.string.settings_category_account))
|
||||||
}
|
}
|
||||||
|
|
||||||
ListItem(
|
SettingsListItem(
|
||||||
headlineContent = {
|
first = true,
|
||||||
Text(
|
headlineContent = { Text(text = stringResource(id = R.string.settings_account)) },
|
||||||
text = stringResource(id = R.string.settings_account)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
SettingsIcon {
|
SettingsIcon {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -122,17 +123,11 @@ fun SettingsScreen(
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.testTag("settings_view_account")
|
.testTag("settings_view_account")
|
||||||
.clickable {
|
.clickable { navController.navigate("settings/account") }
|
||||||
navController.navigate("settings/account")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
Spacer(Modifier.height(2.dp))
|
||||||
ListItem(
|
SettingsListItem(
|
||||||
headlineContent = {
|
headlineContent = { Text(text = stringResource(id = R.string.settings_profile)) },
|
||||||
Text(
|
|
||||||
text = stringResource(id = R.string.settings_profile)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
SettingsIcon {
|
SettingsIcon {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -143,17 +138,12 @@ fun SettingsScreen(
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.testTag("settings_view_profile")
|
.testTag("settings_view_profile")
|
||||||
.clickable {
|
.clickable { navController.navigate("settings/profile") }
|
||||||
navController.navigate("settings/profile")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
Spacer(Modifier.height(2.dp))
|
||||||
ListItem(
|
SettingsListItem(
|
||||||
headlineContent = {
|
last = true,
|
||||||
Text(
|
headlineContent = { Text(text = stringResource(id = R.string.settings_sessions)) },
|
||||||
text = stringResource(id = R.string.settings_sessions)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
SettingsIcon {
|
SettingsIcon {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -164,21 +154,16 @@ fun SettingsScreen(
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.testTag("settings_view_sessions")
|
.testTag("settings_view_sessions")
|
||||||
.clickable {
|
.clickable { navController.navigate("settings/sessions") }
|
||||||
navController.navigate("settings/sessions")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ListHeader {
|
ListHeader {
|
||||||
Text(stringResource(R.string.settings_category_general))
|
Text(stringResource(R.string.settings_category_general))
|
||||||
}
|
}
|
||||||
|
|
||||||
ListItem(
|
SettingsListItem(
|
||||||
headlineContent = {
|
first = true,
|
||||||
Text(
|
headlineContent = { Text(text = stringResource(id = R.string.settings_appearance)) },
|
||||||
text = stringResource(id = R.string.settings_appearance)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
SettingsIcon {
|
SettingsIcon {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -189,17 +174,11 @@ fun SettingsScreen(
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.testTag("settings_view_appearance")
|
.testTag("settings_view_appearance")
|
||||||
.clickable {
|
.clickable { navController.navigate("settings/appearance") }
|
||||||
navController.navigate("settings/appearance")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
Spacer(Modifier.height(2.dp))
|
||||||
ListItem(
|
SettingsListItem(
|
||||||
headlineContent = {
|
headlineContent = { Text(text = stringResource(id = R.string.settings_language)) },
|
||||||
Text(
|
|
||||||
text = stringResource(id = R.string.settings_language)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
SettingsIcon {
|
SettingsIcon {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -210,17 +189,11 @@ fun SettingsScreen(
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.testTag("settings_view_language")
|
.testTag("settings_view_language")
|
||||||
.clickable {
|
.clickable { navController.navigate("settings/language") }
|
||||||
navController.navigate("settings/language")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
Spacer(Modifier.height(2.dp))
|
||||||
ListItem(
|
SettingsListItem(
|
||||||
headlineContent = {
|
headlineContent = { Text(text = stringResource(id = R.string.settings_chat)) },
|
||||||
Text(
|
|
||||||
text = stringResource(id = R.string.settings_chat)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
SettingsIcon {
|
SettingsIcon {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -231,16 +204,12 @@ fun SettingsScreen(
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.testTag("settings_view_chat")
|
.testTag("settings_view_chat")
|
||||||
.clickable {
|
.clickable { navController.navigate("settings/chat") }
|
||||||
navController.navigate("settings/chat")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
ListItem(
|
Spacer(Modifier.height(2.dp))
|
||||||
headlineContent = {
|
SettingsListItem(
|
||||||
Text(
|
last = true,
|
||||||
text = stringResource(id = R.string.settings_notifications)
|
headlineContent = { Text(text = stringResource(id = R.string.settings_notifications)) },
|
||||||
)
|
|
||||||
},
|
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
SettingsIcon {
|
SettingsIcon {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -251,21 +220,25 @@ fun SettingsScreen(
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.testTag("settings_view_notifications")
|
.testTag("settings_view_notifications")
|
||||||
.clickable {
|
.clickable { navController.navigate("settings/notifications") }
|
||||||
navController.navigate("settings/notifications")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ListHeader {
|
ListHeader {
|
||||||
Text(stringResource(R.string.settings_category_miscellaneous))
|
Text(stringResource(R.string.settings_category_miscellaneous))
|
||||||
}
|
}
|
||||||
|
|
||||||
ListItem(
|
val miscLastIsExperiments = LoadedSettings.experimentsEnabled
|
||||||
headlineContent = {
|
val miscLastIsLabs =
|
||||||
Text(
|
!miscLastIsExperiments && FeatureFlags.labsAccessControlGranted
|
||||||
text = stringResource(id = R.string.about)
|
val miscLastIsDebug =
|
||||||
)
|
!miscLastIsExperiments && !miscLastIsLabs && BuildConfig.DEBUG
|
||||||
},
|
val miscLastIsAbout =
|
||||||
|
!miscLastIsExperiments && !miscLastIsLabs && !miscLastIsDebug
|
||||||
|
|
||||||
|
SettingsListItem(
|
||||||
|
first = true,
|
||||||
|
last = miscLastIsAbout,
|
||||||
|
headlineContent = { Text(text = stringResource(id = R.string.about)) },
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
SettingsIcon {
|
SettingsIcon {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -276,18 +249,14 @@ fun SettingsScreen(
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.testTag("settings_view_about")
|
.testTag("settings_view_about")
|
||||||
.clickable {
|
.clickable { navController.navigate("about") }
|
||||||
navController.navigate("about")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
ListItem(
|
Spacer(Modifier.height(2.dp))
|
||||||
headlineContent = {
|
SettingsListItem(
|
||||||
Text(
|
last = miscLastIsDebug,
|
||||||
text = "Debug"
|
headlineContent = { Text(text = "Debug") },
|
||||||
)
|
|
||||||
},
|
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
SettingsIcon {
|
SettingsIcon {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -298,19 +267,15 @@ fun SettingsScreen(
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.testTag("settings_view_debug")
|
.testTag("settings_view_debug")
|
||||||
.clickable {
|
.clickable { navController.navigate("settings/debug") }
|
||||||
navController.navigate("settings/debug")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FeatureFlags.labsAccessControlGranted) {
|
if (FeatureFlags.labsAccessControlGranted) {
|
||||||
ListItem(
|
Spacer(Modifier.height(2.dp))
|
||||||
headlineContent = {
|
SettingsListItem(
|
||||||
Text(
|
last = miscLastIsLabs,
|
||||||
text = "Labs"
|
headlineContent = { Text(text = "Labs") },
|
||||||
)
|
|
||||||
},
|
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
SettingsIcon {
|
SettingsIcon {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -321,19 +286,15 @@ fun SettingsScreen(
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.testTag("settings_view_labs")
|
.testTag("settings_view_labs")
|
||||||
.clickable {
|
.clickable { navController.navigate("labs") }
|
||||||
navController.navigate("labs")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LoadedSettings.experimentsEnabled) {
|
if (LoadedSettings.experimentsEnabled) {
|
||||||
ListItem(
|
Spacer(Modifier.height(2.dp))
|
||||||
headlineContent = {
|
SettingsListItem(
|
||||||
Text(
|
last = true,
|
||||||
text = "Experiments"
|
headlineContent = { Text(text = "Experiments") },
|
||||||
)
|
|
||||||
},
|
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
SettingsIcon {
|
SettingsIcon {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -344,9 +305,7 @@ fun SettingsScreen(
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.testTag("settings_view_experiments")
|
.testTag("settings_view_experiments")
|
||||||
.clickable {
|
.clickable { navController.navigate("settings/experiments") }
|
||||||
navController.navigate("settings/experiments")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -359,12 +318,9 @@ fun SettingsScreen(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
ListItem(
|
SettingsListItem(
|
||||||
headlineContent = {
|
first = true,
|
||||||
Text(
|
headlineContent = { Text(text = stringResource(id = R.string.settings_changelog)) },
|
||||||
text = stringResource(id = R.string.settings_changelog)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
SettingsIcon {
|
SettingsIcon {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -375,22 +331,12 @@ fun SettingsScreen(
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.testTag("settings_view_changelog")
|
.testTag("settings_view_changelog")
|
||||||
.clickable {
|
.clickable { navController.navigate("changelog/latest") }
|
||||||
navController.navigate("changelog/latest")
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
Spacer(Modifier.height(2.dp))
|
||||||
ListItem(
|
SettingsListItem(
|
||||||
headlineContent = {
|
headlineContent = { Text(text = stringResource(id = R.string.settings_feedback)) },
|
||||||
Text(
|
supportingContent = { Text(text = stringResource(id = R.string.settings_feedback_description)) },
|
||||||
text = stringResource(id = R.string.settings_feedback)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
supportingContent = {
|
|
||||||
Text(
|
|
||||||
text = stringResource(id = R.string.settings_feedback_description)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
SettingsIcon {
|
SettingsIcon {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -406,18 +352,16 @@ fun SettingsScreen(
|
||||||
context,
|
context,
|
||||||
InviteActivity::class.java
|
InviteActivity::class.java
|
||||||
).setAction(Intent.ACTION_VIEW)
|
).setAction(Intent.ACTION_VIEW)
|
||||||
|
|
||||||
intent.data = "https://stt.gg/Testers".toUri()
|
intent.data = "https://stt.gg/Testers".toUri()
|
||||||
context.startActivity(intent)
|
context.startActivity(intent)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Spacer(Modifier.height(2.dp))
|
||||||
ListItem(
|
SettingsListItem(
|
||||||
|
last = true,
|
||||||
headlineContent = {
|
headlineContent = {
|
||||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.error) {
|
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.error) {
|
||||||
Text(
|
Text(text = stringResource(id = R.string.logout))
|
||||||
text = stringResource(id = R.string.logout)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
|
|
@ -445,6 +389,42 @@ fun SettingsScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun SettingsListItem(
|
||||||
|
first: Boolean = false,
|
||||||
|
last: Boolean = false,
|
||||||
|
headlineContent: @Composable () -> Unit,
|
||||||
|
supportingContent: (@Composable () -> Unit)? = null,
|
||||||
|
leadingContent: (@Composable () -> Unit)? = null,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
ListItem(
|
||||||
|
colors = ListItemDefaults.colors(containerColor = MaterialTheme.colorScheme.surfaceContainer),
|
||||||
|
headlineContent = headlineContent,
|
||||||
|
supportingContent = supportingContent,
|
||||||
|
leadingContent = leadingContent,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.clip(
|
||||||
|
when {
|
||||||
|
first && last -> MaterialTheme.shapes.large
|
||||||
|
first -> MaterialTheme.shapes.extraSmall.copy(
|
||||||
|
topStart = MaterialTheme.shapes.large.topStart,
|
||||||
|
topEnd = MaterialTheme.shapes.large.topEnd
|
||||||
|
)
|
||||||
|
|
||||||
|
last -> MaterialTheme.shapes.extraSmall.copy(
|
||||||
|
bottomStart = MaterialTheme.shapes.large.bottomStart,
|
||||||
|
bottomEnd = MaterialTheme.shapes.large.bottomEnd
|
||||||
|
)
|
||||||
|
|
||||||
|
else -> MaterialTheme.shapes.extraSmall
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(modifier)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsIcon(danger: Boolean = false, content: @Composable () -> Unit) {
|
fun SettingsIcon(danger: Boolean = false, content: @Composable () -> Unit) {
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
|
|
@ -454,4 +434,4 @@ fun SettingsIcon(danger: Boolean = false, content: @Composable () -> Unit) {
|
||||||
) {
|
) {
|
||||||
content()
|
content()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,12 @@ import android.app.Application
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.compose.animation.animateContentSize
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.combinedClickable
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
|
@ -311,47 +312,58 @@ fun MemberListSheet(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is MemberListSheetItem.MemberItem -> item(key = item.member.id!!.user) {
|
is MemberListSheetItem.MemberItem -> {
|
||||||
MemberListItem(
|
val isFirst = index == 0 || viewModel.fullItemList[index - 1] is MemberListSheetItem.CategoryItem
|
||||||
user = StoatAPI.userCache[item.member.id!!.user],
|
val isLast = index == viewModel.fullItemList.size - 1 || viewModel.fullItemList[index + 1] is MemberListSheetItem.CategoryItem
|
||||||
member = item.member,
|
item(key = item.member.id!!.user) {
|
||||||
serverId = serverId,
|
MemberListItem(
|
||||||
userId = item.member.id!!.user,
|
user = StoatAPI.userCache[item.member.id!!.user],
|
||||||
modifier = Modifier
|
member = item.member,
|
||||||
.combinedClickable(
|
serverId = serverId,
|
||||||
onClick = {
|
userId = item.member.id!!.user,
|
||||||
userInfoSheetTarget = item.member.id!!.user
|
first = isFirst,
|
||||||
showUserInfoSheet = true
|
last = isLast,
|
||||||
},
|
onClick = {
|
||||||
onClickLabel = stringResource(R.string.user_info_sheet_open),
|
userInfoSheetTarget = item.member.id!!.user
|
||||||
onLongClick = {
|
showUserInfoSheet = true
|
||||||
memberContextSheetTarget = item.member.id!!.user
|
},
|
||||||
showMemberContextSheet = true
|
onLongClick = {
|
||||||
},
|
memberContextSheetTarget = item.member.id!!.user
|
||||||
onLongClickLabel = stringResource(R.string.member_context_sheet_open)
|
showMemberContextSheet = true
|
||||||
)
|
},
|
||||||
)
|
modifier = Modifier.padding(horizontal = 16.dp)
|
||||||
|
)
|
||||||
|
if (!isLast) {
|
||||||
|
Spacer(modifier = Modifier.height(2.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is MemberListSheetItem.UserItem -> item(key = item.user.id!!) {
|
is MemberListSheetItem.UserItem -> {
|
||||||
MemberListItem(
|
val isFirst = index == 0 || viewModel.fullItemList[index - 1] is MemberListSheetItem.CategoryItem
|
||||||
user = item.user,
|
val isLast = index == viewModel.fullItemList.size - 1 || viewModel.fullItemList[index + 1] is MemberListSheetItem.CategoryItem
|
||||||
member = null,
|
item(key = item.user.id!!) {
|
||||||
serverId = serverId,
|
MemberListItem(
|
||||||
userId = item.user.id!!,
|
user = item.user,
|
||||||
modifier = Modifier.combinedClickable(
|
member = null,
|
||||||
|
serverId = serverId,
|
||||||
|
userId = item.user.id!!,
|
||||||
|
first = isFirst,
|
||||||
|
last = isLast,
|
||||||
onClick = {
|
onClick = {
|
||||||
userInfoSheetTarget = item.user.id!!
|
userInfoSheetTarget = item.user.id!!
|
||||||
showUserInfoSheet = true
|
showUserInfoSheet = true
|
||||||
},
|
},
|
||||||
onClickLabel = stringResource(R.string.user_info_sheet_open),
|
|
||||||
onLongClick = {
|
onLongClick = {
|
||||||
memberContextSheetTarget = item.user.id!!
|
memberContextSheetTarget = item.user.id!!
|
||||||
showMemberContextSheet = true
|
showMemberContextSheet = true
|
||||||
},
|
},
|
||||||
onLongClickLabel = stringResource(R.string.member_context_sheet_open)
|
modifier = Modifier.padding(horizontal = 16.dp)
|
||||||
)
|
)
|
||||||
)
|
if (!isLast) {
|
||||||
|
Spacer(modifier = Modifier.height(2.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
|
|
@ -218,9 +218,9 @@ fun ReactionInfoSheet(messageId: String, emoji: String, onDismiss: () -> Unit) {
|
||||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
modifier = Modifier.padding(
|
modifier = Modifier.padding(
|
||||||
top = 16.dp,
|
top = 16.dp,
|
||||||
start = 16.dp,
|
start = 24.dp,
|
||||||
end = 16.dp,
|
end = 24.dp,
|
||||||
bottom = 4.dp
|
bottom = 16.dp
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
|
|
@ -308,15 +308,14 @@ fun ReactionInfoSheet(messageId: String, emoji: String, onDismiss: () -> Unit) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalDivider()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val reactionsForEmoji =
|
val reactionsForEmoji =
|
||||||
reactions?.get(reactionEmoji[selectedReactionIndex]) ?: emptyList()
|
reactions?.get(reactionEmoji[selectedReactionIndex]) ?: emptyList()
|
||||||
items(items = reactionsForEmoji) { reaction ->
|
itemsIndexed(items = reactionsForEmoji) { index, reaction ->
|
||||||
|
val isLast = index == reactionsForEmoji.size - 1
|
||||||
val userOrNull = StoatAPI.userCache[reaction]
|
val userOrNull = StoatAPI.userCache[reaction]
|
||||||
val user = userOrNull ?: User.getPlaceholder(reaction)
|
val user = userOrNull ?: User.getPlaceholder(reaction)
|
||||||
val member = if (channel.server != null && user.id != null) {
|
val member = if (channel.server != null && user.id != null) {
|
||||||
|
|
@ -340,7 +339,13 @@ fun ReactionInfoSheet(messageId: String, emoji: String, onDismiss: () -> Unit) {
|
||||||
user = user,
|
user = user,
|
||||||
serverId = channel.server,
|
serverId = channel.server,
|
||||||
userId = reaction,
|
userId = reaction,
|
||||||
|
first = index == 0,
|
||||||
|
last = isLast,
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp)
|
||||||
)
|
)
|
||||||
|
if (!isLast) {
|
||||||
|
Spacer(modifier = Modifier.height(2.dp))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
item("bottom") {
|
item("bottom") {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue