feat: revamp server name and banner display
also adds a bottom sheet and fixes an NPE Signed-off-by: Infi <wingit@geist.ga>
This commit is contained in:
parent
5db3d6f401
commit
8b7c36337b
|
|
@ -1,7 +1,8 @@
|
||||||
package chat.revolt.components.generic
|
package chat.revolt.components.generic
|
||||||
|
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
|
@ -13,18 +14,23 @@ import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun IconPlaceholder(
|
fun IconPlaceholder(
|
||||||
name: String,
|
name: String,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onClick: () -> Unit = {},
|
onClick: () -> Unit = {},
|
||||||
|
onLongClick: () -> Unit = {}
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp))
|
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp))
|
||||||
.then(
|
.then(
|
||||||
if (onClick != {}) Modifier.clickable(onClick = onClick)
|
if (onClick != {} || onLongClick != {}) Modifier.combinedClickable(
|
||||||
|
onClick = onClick,
|
||||||
|
onLongClick = onLongClick
|
||||||
|
)
|
||||||
else Modifier
|
else Modifier
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ fun UIMarkdown(
|
||||||
memberMap = mapOf(),
|
memberMap = mapOf(),
|
||||||
userMap = RevoltAPI.userCache.toMap(),
|
userMap = RevoltAPI.userCache.toMap(),
|
||||||
channelMap = RevoltAPI.channelCache.mapValues { ch ->
|
channelMap = RevoltAPI.channelCache.mapValues { ch ->
|
||||||
ch.value.name ?: ch.value.id!!
|
ch.value.name ?: ch.value.id ?: "{this does not exist 🤫}"
|
||||||
},
|
},
|
||||||
emojiMap = RevoltAPI.emojiCache,
|
emojiMap = RevoltAPI.emojiCache,
|
||||||
serverId = null
|
serverId = null
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,52 @@
|
||||||
package chat.revolt.components.screens.chat.drawer.channel
|
package chat.revolt.components.screens.chat.drawer.channel
|
||||||
|
|
||||||
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.RowScope
|
import androidx.compose.foundation.layout.RowScope
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
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.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.MoreVert
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.ModalBottomSheet
|
import androidx.compose.material3.ModalBottomSheet
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.rememberModalBottomSheetState
|
import androidx.compose.material3.rememberModalBottomSheetState
|
||||||
|
import androidx.compose.material3.surfaceColorAtElevation
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import chat.revolt.R
|
import chat.revolt.R
|
||||||
|
import chat.revolt.activities.RevoltTweenDp
|
||||||
|
import chat.revolt.activities.RevoltTweenFloat
|
||||||
import chat.revolt.api.REVOLT_FILES
|
import chat.revolt.api.REVOLT_FILES
|
||||||
import chat.revolt.api.RevoltAPI
|
import chat.revolt.api.RevoltAPI
|
||||||
import chat.revolt.api.internals.ChannelUtils
|
import chat.revolt.api.internals.ChannelUtils
|
||||||
|
|
@ -37,8 +56,12 @@ import chat.revolt.components.generic.RemoteImage
|
||||||
import chat.revolt.components.generic.presenceFromStatus
|
import chat.revolt.components.generic.presenceFromStatus
|
||||||
import chat.revolt.components.screens.chat.drawer.server.DrawerChannel
|
import chat.revolt.components.screens.chat.drawer.server.DrawerChannel
|
||||||
import chat.revolt.sheets.ChannelContextSheet
|
import chat.revolt.sheets.ChannelContextSheet
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
const val BANNER_HEIGHT_COMPACT = 56
|
||||||
|
const val BANNER_HEIGHT_EXPANDED = 128
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun RowScope.ChannelList(
|
fun RowScope.ChannelList(
|
||||||
serverId: String,
|
serverId: String,
|
||||||
|
|
@ -46,7 +69,27 @@ fun RowScope.ChannelList(
|
||||||
currentChannel: String?,
|
currentChannel: String?,
|
||||||
onChannelClick: (String) -> Unit,
|
onChannelClick: (String) -> Unit,
|
||||||
onSpecialClick: (String) -> Unit,
|
onSpecialClick: (String) -> Unit,
|
||||||
|
onServerSheetOpenFor: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val lazyListState = rememberLazyListState()
|
||||||
|
val enableSmallBanner by remember {
|
||||||
|
derivedStateOf {
|
||||||
|
lazyListState.firstVisibleItemScrollOffset > 40 ||
|
||||||
|
lazyListState.firstVisibleItemIndex > 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val bannerHeight by animateDpAsState(
|
||||||
|
targetValue = if (enableSmallBanner) BANNER_HEIGHT_COMPACT.dp else BANNER_HEIGHT_EXPANDED.dp,
|
||||||
|
animationSpec = RevoltTweenDp,
|
||||||
|
label = "Banner Height"
|
||||||
|
)
|
||||||
|
val bannerImageOpacity by animateFloatAsState(
|
||||||
|
targetValue = if (enableSmallBanner) 0f else 1f,
|
||||||
|
animationSpec = RevoltTweenFloat,
|
||||||
|
label = "Banner Image Opacity"
|
||||||
|
)
|
||||||
|
|
||||||
var channelContextSheetShown by remember { mutableStateOf(false) }
|
var channelContextSheetShown by remember { mutableStateOf(false) }
|
||||||
var channelContextSheetTarget by remember { mutableStateOf("") }
|
var channelContextSheetTarget by remember { mutableStateOf("") }
|
||||||
|
|
||||||
|
|
@ -87,17 +130,30 @@ fun RowScope.ChannelList(
|
||||||
Modifier
|
Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
|
state = lazyListState,
|
||||||
) {
|
) {
|
||||||
if (serverId == "home") {
|
if (serverId == "home") {
|
||||||
item(
|
stickyHeader(
|
||||||
key = "header"
|
key = "header"
|
||||||
) {
|
) {
|
||||||
Text(
|
Box(
|
||||||
text = stringResource(R.string.direct_messages),
|
modifier = Modifier
|
||||||
style = MaterialTheme.typography.labelLarge,
|
.padding(start = 8.dp, end = 8.dp, top = 0.dp, bottom = 8.dp)
|
||||||
fontSize = 24.sp,
|
.alpha(0.9f)
|
||||||
modifier = Modifier.padding(16.dp)
|
.height(BANNER_HEIGHT_COMPACT.dp + 8.dp) // due to padding in Text
|
||||||
)
|
.fillMaxWidth()
|
||||||
|
.clip(RoundedCornerShape(16.dp))
|
||||||
|
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp))
|
||||||
|
.weight(1f)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.direct_messages),
|
||||||
|
style = MaterialTheme.typography.labelLarge,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(start = 16.dp, end = 16.dp, top = 24.dp, bottom = 16.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
item(
|
item(
|
||||||
|
|
@ -189,28 +245,110 @@ fun RowScope.ChannelList(
|
||||||
} else {
|
} else {
|
||||||
val server = RevoltAPI.serverCache[serverId]
|
val server = RevoltAPI.serverCache[serverId]
|
||||||
|
|
||||||
item {
|
stickyHeader {
|
||||||
Text(
|
Box(
|
||||||
text = server?.name
|
contentAlignment = Alignment.BottomStart,
|
||||||
?: stringResource(R.string.unknown),
|
modifier = Modifier
|
||||||
style = MaterialTheme.typography.labelLarge,
|
.then(
|
||||||
fontSize = 24.sp,
|
// if there is no banner, we change the design slightly.
|
||||||
modifier = Modifier.padding(16.dp)
|
// instead of there being a banner card we make a "classic"
|
||||||
)
|
// sticky header á la Google Messages
|
||||||
}
|
if (server?.banner != null) {
|
||||||
|
Modifier.padding(vertical = 8.dp, horizontal = 8.dp)
|
||||||
|
} else {
|
||||||
|
Modifier.padding(
|
||||||
|
start = 0.dp,
|
||||||
|
end = 8.dp,
|
||||||
|
top = 0.dp,
|
||||||
|
bottom = 0.dp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
if (server?.banner != null) {
|
||||||
|
Box(modifier = Modifier.height(bannerHeight)) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.alpha(max(0.95f, bannerImageOpacity))
|
||||||
|
.fillMaxSize()
|
||||||
|
.clip(RoundedCornerShape(16.dp))
|
||||||
|
.background(MaterialTheme.colorScheme.surface)
|
||||||
|
)
|
||||||
|
|
||||||
server?.banner?.let {
|
RemoteImage(
|
||||||
item {
|
url = "$REVOLT_FILES/banners/${server.banner.id}",
|
||||||
RemoteImage(
|
description = null,
|
||||||
url = "$REVOLT_FILES/banners/${it.id}",
|
modifier = Modifier
|
||||||
description = null,
|
.alpha(bannerImageOpacity)
|
||||||
modifier = Modifier
|
.fillMaxSize()
|
||||||
.fillMaxWidth()
|
.clip(RoundedCornerShape(16.dp))
|
||||||
.height(200.dp)
|
)
|
||||||
.padding(start = 16.dp, end = 16.dp, top = 0.dp, bottom = 16.dp)
|
|
||||||
.clip(RoundedCornerShape(16.dp))
|
Box(
|
||||||
)
|
modifier = Modifier
|
||||||
|
.alpha(bannerImageOpacity)
|
||||||
|
.fillMaxSize()
|
||||||
|
.clip(RoundedCornerShape(16.dp))
|
||||||
|
.background(
|
||||||
|
Brush.verticalGradient(
|
||||||
|
listOf(
|
||||||
|
Color.Transparent,
|
||||||
|
Color.Black.copy(alpha = 0.3f)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.alpha(0.9f)
|
||||||
|
.height(BANNER_HEIGHT_COMPACT.dp + 8.dp) // due to padding in Text
|
||||||
|
.fillMaxWidth()
|
||||||
|
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = (server?.name
|
||||||
|
?: stringResource(R.string.unknown)),
|
||||||
|
style = MaterialTheme.typography.labelLarge,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
modifier = Modifier
|
||||||
|
.then(
|
||||||
|
if (server?.banner != null) {
|
||||||
|
Modifier.padding(16.dp)
|
||||||
|
} else {
|
||||||
|
Modifier.padding(
|
||||||
|
start = 24.dp,
|
||||||
|
end = 24.dp,
|
||||||
|
top = 16.dp,
|
||||||
|
bottom = 16.dp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.weight(1f),
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis
|
||||||
|
)
|
||||||
|
|
||||||
|
IconButton(onClick = {
|
||||||
|
onServerSheetOpenFor(serverId)
|
||||||
|
}) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.MoreVert,
|
||||||
|
contentDescription = stringResource(
|
||||||
|
id = R.string.settings
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server?.channels?.isEmpty() == true) {
|
if (server?.channels?.isEmpty() == true) {
|
||||||
|
|
@ -242,8 +380,8 @@ fun RowScope.ChannelList(
|
||||||
server?.channels?.get(it)?.let { channelId ->
|
server?.channels?.get(it)?.let { channelId ->
|
||||||
RevoltAPI.channelCache[channelId]?.let { ch ->
|
RevoltAPI.channelCache[channelId]?.let { ch ->
|
||||||
DrawerChannel(
|
DrawerChannel(
|
||||||
name = ch.name!!,
|
name = ch.name ?: stringResource(R.string.unknown),
|
||||||
channelType = ch.channelType!!,
|
channelType = ch.channelType ?: ChannelType.TextChannel,
|
||||||
selected = currentDestination == "channel/{channelId}" && currentChannel == ch.id,
|
selected = currentDestination == "channel/{channelId}" && currentChannel == ch.id,
|
||||||
hasUnread = ch.lastMessageID?.let { lastMessageID ->
|
hasUnread = ch.lastMessageID?.let { lastMessageID ->
|
||||||
RevoltAPI.unreads.hasUnread(
|
RevoltAPI.unreads.hasUnread(
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,9 @@ package chat.revolt.components.screens.chat.drawer.server
|
||||||
|
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.animation.core.spring
|
import androidx.compose.animation.core.spring
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.offset
|
import androidx.compose.foundation.layout.offset
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
|
@ -20,11 +21,13 @@ import chat.revolt.api.REVOLT_FILES
|
||||||
import chat.revolt.components.generic.IconPlaceholder
|
import chat.revolt.components.generic.IconPlaceholder
|
||||||
import chat.revolt.components.generic.RemoteImage
|
import chat.revolt.components.generic.RemoteImage
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun DrawerServer(
|
fun DrawerServer(
|
||||||
iconId: String?,
|
iconId: String?,
|
||||||
serverName: String,
|
serverName: String,
|
||||||
hasUnreads: Boolean,
|
hasUnreads: Boolean,
|
||||||
|
onLongClick: () -> Unit,
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
val unreadIndicatorAlpha = animateFloatAsState(
|
val unreadIndicatorAlpha = animateFloatAsState(
|
||||||
|
|
@ -43,13 +46,17 @@ fun DrawerServer(
|
||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
.size(48.dp)
|
.size(48.dp)
|
||||||
.clip(CircleShape)
|
.clip(CircleShape)
|
||||||
.clickable(onClick = onClick),
|
.combinedClickable(
|
||||||
|
onClick = onClick,
|
||||||
|
onLongClick = onLongClick
|
||||||
|
),
|
||||||
description = serverName
|
description = serverName
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
IconPlaceholder(
|
IconPlaceholder(
|
||||||
name = serverName,
|
name = serverName,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
|
onLongClick = onLongClick,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
.size(48.dp)
|
.size(48.dp)
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,9 @@ fun ChatRouterScreen(topNav: NavController, viewModel: ChatRouterViewModel = hil
|
||||||
var showStatusSheet by remember { mutableStateOf(false) }
|
var showStatusSheet by remember { mutableStateOf(false) }
|
||||||
var showAddServerSheet by remember { mutableStateOf(false) }
|
var showAddServerSheet by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
var showServerContextSheet by remember { mutableStateOf(false) }
|
||||||
|
var serverContextSheetTarget by remember { mutableStateOf("") }
|
||||||
|
|
||||||
BackHandler(enabled = drawerState.isClosed) {
|
BackHandler(enabled = drawerState.isClosed) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
drawerState.open()
|
drawerState.open()
|
||||||
|
|
@ -304,6 +307,22 @@ fun ChatRouterScreen(topNav: NavController, viewModel: ChatRouterViewModel = hil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (showServerContextSheet) {
|
||||||
|
val serverContextSheetState = rememberModalBottomSheetState()
|
||||||
|
|
||||||
|
ModalBottomSheet(
|
||||||
|
sheetState = serverContextSheetState,
|
||||||
|
onDismissRequest = {
|
||||||
|
showServerContextSheet = false
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Column {
|
||||||
|
Text(text = "this is server context sheet for $serverContextSheetTarget")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
|
@ -385,6 +404,10 @@ fun ChatRouterScreen(topNav: NavController, viewModel: ChatRouterViewModel = hil
|
||||||
hasUnreads = RevoltAPI.unreads.serverHasUnread(
|
hasUnreads = RevoltAPI.unreads.serverHasUnread(
|
||||||
server.id
|
server.id
|
||||||
),
|
),
|
||||||
|
onLongClick = {
|
||||||
|
serverContextSheetTarget = server.id
|
||||||
|
showServerContextSheet = true
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
viewModel.navigateToServer(
|
viewModel.navigateToServer(
|
||||||
server.id,
|
server.id,
|
||||||
|
|
@ -422,6 +445,10 @@ fun ChatRouterScreen(topNav: NavController, viewModel: ChatRouterViewModel = hil
|
||||||
viewModel.navigateToSpecial(destination, navController)
|
viewModel.navigateToSpecial(destination, navController)
|
||||||
scope.launch { drawerState.close() }
|
scope.launch { drawerState.close() }
|
||||||
},
|
},
|
||||||
|
onServerSheetOpenFor = { target ->
|
||||||
|
serverContextSheetTarget = target
|
||||||
|
showServerContextSheet = true
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue