refactor: Enhance ChannelSideDrawer and ServerContextSheet for improved user interactions

This commit refines the user interaction handling in ChannelSideDrawer and ServerContextSheet components.

- Improved the layout and click handling in ChannelSideDrawer for better user experience.
- Updated ServerContextSheet to handle server actions more efficiently, including copying server IDs and marking servers as read.
- Introduced a confirmation dialog for leaving servers and improved error handling during server actions.
- Cleaned up code for better readability and maintainability across the affected files.
This commit is contained in:
AbronStudio 2025-08-20 12:57:26 +03:30
parent c2790838df
commit e2a3fb38af
3 changed files with 141 additions and 103 deletions

View File

@ -320,24 +320,27 @@ fun ChannelSideDrawer(
Box(
Modifier
.padding(8.dp)
.clip(animateDpAsState(
targetValue = if (currentDestination is ChatRouterDestination.Discover) 16.dp else 24.dp,
animationSpec = spring(stiffness = Spring.StiffnessMediumLow),
label = "Discover button corner radius"
).value.let { RoundedCornerShape(it) })
.clip(
animateDpAsState(
targetValue = if (currentDestination is ChatRouterDestination.Discover) 16.dp else 24.dp,
animationSpec = spring(stiffness = Spring.StiffnessMediumLow),
label = "Discover button corner radius"
).value.let { RoundedCornerShape(it) })
.clickable {
onDestinationChanged(
ChatRouterDestination.Discover
)
}
.size(48.dp)
.background(animateColorAsState(
targetValue = if (currentDestination is ChatRouterDestination.Discover) {
.background(
animateColorAsState(
targetValue = if (currentDestination is ChatRouterDestination.Discover) {
MaterialTheme.colorScheme.secondaryContainer
} else MaterialTheme.colorScheme.primaryContainer,
animationSpec = spring(stiffness = Spring.StiffnessMediumLow),
label = "Discover button background"
).value),
animationSpec = spring(stiffness = Spring.StiffnessMediumLow),
label = "Discover button background"
).value
),
contentAlignment = Alignment.Center
) {
Icon(
@ -402,14 +405,21 @@ fun ChannelSideDrawer(
label = "Left indicator colour"
)
Box(Modifier.fillMaxWidth()) {
Box(
Modifier
.padding(8.dp)
.clip(CircleShape)
.clickable {
Box(
Modifier
.fillMaxWidth()
.combinedClickable(
onClick = {
serverInList.id?.let { srvId -> navigateToServer(srvId) }
}) {
},
onLongClick = {
serverInList.id?.let { srvId -> onShowServerContextSheet(srvId) }
}
)
) {
Box(
Modifier.padding(8.dp)
) {
val icon = serverInList.icon?.id?.let { iconId ->
"${PeptideAPI.getCurrentFilesUrl()}/icons/$iconId"
}
@ -828,7 +838,7 @@ private fun ColumnScope.DirectMessagesChannelListRenderer(
onDestinationChanged(dest)
},
onOpenChannelContextSheet = {},
onOpenUserInfoSheet = {userId -> onOpenUserInfoSheet(userId)}
onOpenUserInfoSheet = { userId -> onOpenUserInfoSheet(userId) }
)
}
}

View File

@ -623,7 +623,7 @@ fun ChatRouterScreen(
showServerContextSheet = false
},
onReportServer = {
reportServerTarget = currentServer ?: ""
reportServerTarget = serverContextSheetTarget
showReportServer = true
}
)

View File

@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
@ -31,6 +32,8 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
@ -47,7 +50,10 @@ import chat.peptide.composables.generic.SquareButton
import chat.peptide.composables.markdown.RichMarkdown
import chat.peptide.composables.screens.settings.ServerOverview
import chat.peptide.composables.sheets.SheetSelection
import chat.peptide.callbacks.Action
import chat.peptide.callbacks.ActionChannel
import chat.peptide.internals.Platform
import chat.peptide.screens.chat.ChatRouterDestination
import kotlinx.coroutines.launch
@Composable
@ -56,25 +62,25 @@ fun ServerContextSheet(
onReportServer: () -> Unit,
onHideSheet: suspend () -> Unit
) {
val server = PeptideAPI.serverCache[serverId]
if (server == null) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
) {
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
}
return
}
val coroutineScope = rememberCoroutineScope()
val clipboardManager = LocalClipboardManager.current
val context = LocalContext.current
var showLeaveConfirmation by remember { mutableStateOf(false) }
var leaveSilently by remember { mutableStateOf(false) }
val server = PeptideAPI.serverCache[serverId]
LaunchedEffect(server) {
if (server == null) {
coroutineScope.launch {
onHideSheet()
}
}
}
if (server == null) {
return
}
if (showLeaveConfirmation) {
AlertDialog(
@ -119,10 +125,15 @@ fun ServerContextSheet(
SquareButton(
onClick = {
coroutineScope.launch {
onHideSheet()
}
coroutineScope.launch {
leaveOrDeleteServer(serverId, leaveSilently)
try {
leaveOrDeleteServer(serverId, leaveSilently)
PeptideAPI.serverCache.remove(serverId)
ActionChannel.send(Action.ChatNavigate(ChatRouterDestination.Home))
} catch (_: Exception) {
// ignore
} finally {
showLeaveConfirmation = false
}
}
}
) {
@ -200,99 +211,116 @@ fun ServerContextSheet(
}
}
}
HorizontalDivider()
Spacer(modifier = Modifier.height(12.dp))
}
SheetButton(
leadingContent = {
Icon(
painter = painterResource(id = R.drawable.icn_identifier_copy_24dp),
contentDescription = null
)
},
headlineContent = {
Text(
text = stringResource(id = R.string.server_context_sheet_actions_copy_id)
)
},
onClick = {
if (server.id == null) return@SheetButton
clipboardManager.setText(AnnotatedString(server.id))
if (Platform.needsShowClipboardNotification()) {
Toast.makeText(
context,
context.getString(R.string.server_context_sheet_actions_copy_id_copied),
Toast.LENGTH_SHORT
).show()
}
coroutineScope.launch {
onHideSheet()
}
}
)
SheetButton(
leadingContent = {
Icon(
painter = painterResource(id = R.drawable.icn_mark_chat_read_24dp),
contentDescription = null
)
},
headlineContent = {
Text(
text = stringResource(id = R.string.server_context_sheet_actions_mark_read)
)
},
onClick = {
coroutineScope.launch {
server.id?.let {
PeptideAPI.unreads.markServerAsRead(it, sync = true)
}
onHideSheet()
}
}
)
if (server.owner != PeptideAPI.selfId) {
// Primary actions group
Column(
modifier = Modifier
.padding(horizontal = 12.dp)
.clip(RoundedCornerShape(16.dp))
.background(MaterialTheme.colorScheme.surfaceBright)
) {
SheetButton(
leadingContent = {
Icon(
painter = painterResource(id = R.drawable.icn_report_24dp),
painter = painterResource(id = R.drawable.icn_identifier_copy_24dp),
contentDescription = null
)
},
headlineContent = {
Text(
text = stringResource(id = R.string.server_context_sheet_actions_report),
text = stringResource(id = R.string.server_context_sheet_actions_copy_id)
)
},
dangerous = true,
onClick = {
onReportServer()
if (server.id == null) return@SheetButton
clipboardManager.setText(AnnotatedString(server.id))
if (Platform.needsShowClipboardNotification()) {
Toast.makeText(
context,
context.getString(R.string.server_context_sheet_actions_copy_id_copied),
Toast.LENGTH_SHORT
).show()
}
coroutineScope.launch {
onHideSheet()
}
}
)
HorizontalDivider()
SheetButton(
leadingContent = {
Icon(
painter = painterResource(id = R.drawable.icn_door_open_24dp),
contentDescription = null,
painter = painterResource(id = R.drawable.icn_mark_chat_read_24dp),
contentDescription = null
)
},
headlineContent = {
Text(
text = stringResource(id = R.string.server_context_sheet_actions_leave)
text = stringResource(id = R.string.server_context_sheet_actions_mark_read)
)
},
dangerous = true,
onClick = {
showLeaveConfirmation = true
coroutineScope.launch {
server.id?.let {
PeptideAPI.unreads.markServerAsRead(it, sync = true)
}
onHideSheet()
}
}
)
}
// Danger actions group
if (server.owner != PeptideAPI.selfId) {
Column(
modifier = Modifier
.padding(start = 12.dp, end = 12.dp, top = 16.dp)
.clip(RoundedCornerShape(16.dp))
.background(MaterialTheme.colorScheme.surfaceBright)
) {
SheetButton(
leadingContent = {
Icon(
painter = painterResource(id = R.drawable.icn_report_24dp),
contentDescription = null
)
},
headlineContent = {
Text(
text = stringResource(id = R.string.server_context_sheet_actions_report),
)
},
dangerous = true,
onClick = {
onReportServer()
}
)
HorizontalDivider()
SheetButton(
leadingContent = {
Icon(
painter = painterResource(id = R.drawable.icn_door_open_24dp),
contentDescription = null,
)
},
headlineContent = {
Text(
text = stringResource(id = R.string.server_context_sheet_actions_leave)
)
},
dangerous = true,
onClick = {
showLeaveConfirmation = true
}
)
}
}
}
}