Adjusting UI per feedback on official Revolt server. long press will now show the server context menu as a bottom sheet.

This commit is contained in:
Alex Yong 2025-08-13 15:16:01 +00:00
parent fb12b9c6b2
commit e66468830c
2 changed files with 34 additions and 235 deletions

View File

@ -65,4 +65,4 @@
}
],
"configuration_version": "1"
}
}

View File

@ -1,6 +1,5 @@
package chat.revolt.composables.screens.chat.drawer
import android.widget.Toast
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.Spring
@ -38,12 +37,7 @@ import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox
import androidx.compose.material3.DrawerState
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
@ -52,7 +46,6 @@ import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
@ -72,18 +65,14 @@ import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontWeight
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.window.Dialog
import androidx.navigation.NavController
import chat.revolt.R
import chat.revolt.api.REVOLT_FILES
@ -92,7 +81,6 @@ import chat.revolt.api.internals.CategorisedChannelList
import chat.revolt.api.internals.ChannelUtils
import chat.revolt.api.internals.DirectMessages
import chat.revolt.api.internals.FriendRequests
import chat.revolt.api.routes.server.leaveOrDeleteServer
import chat.revolt.api.schemas.Category
import chat.revolt.api.schemas.Channel
import chat.revolt.api.schemas.ChannelType
@ -108,12 +96,11 @@ import chat.revolt.composables.generic.RemoteImage
import chat.revolt.composables.generic.UserAvatar
import chat.revolt.composables.generic.presenceFromStatus
import chat.revolt.composables.screens.chat.ChannelIcon
import chat.revolt.internals.Platform
import chat.revolt.screens.chat.ChatRouterDestination
import chat.revolt.screens.chat.LocalIsConnected
import chat.revolt.screens.chat.dialogs.InviteDialog
import chat.revolt.screens.chat.dialogs.safety.ReportServerDialog
import chat.revolt.sheets.ChannelContextSheet
import chat.revolt.sheets.ServerContextSheet
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
@ -198,11 +185,10 @@ fun ChannelSideDrawer(
}.sortedBy { it.id }))
var channelContextSheetTarget by remember { mutableStateOf<String?>(null) }
var serverContextMenuTarget by remember { mutableStateOf<String?>(null) }
var showLeaveConfirmation by remember { mutableStateOf<String?>(null) }
var leaveSilently by remember { mutableStateOf(false) }
var showReportServerDialog by remember { mutableStateOf<String?>(null) }
var showInviteDialog by remember { mutableStateOf<String?>(null) }
var serverContextSheetTarget by remember { mutableStateOf<String?>(null) }
var showReportServer by remember { mutableStateOf(false) }
var reportServerTarget by remember { mutableStateOf("") }
if (channelContextSheetTarget != null) {
val channelContextSheetState = rememberModalBottomSheetState()
@ -223,118 +209,31 @@ fun ChannelSideDrawer(
}
}
val scope = rememberCoroutineScope()
val clipboardManager = LocalClipboardManager.current
val context = LocalContext.current
if (serverContextSheetTarget != null) {
val serverContextSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
showLeaveConfirmation?.let { serverId ->
val server = RevoltAPI.serverCache[serverId]
AlertDialog(
ModalBottomSheet(
sheetState = serverContextSheetState,
onDismissRequest = {
showLeaveConfirmation = null
leaveSilently = false
},
title = {
Text(
text = stringResource(
id = R.string.server_context_sheet_actions_leave_confirm,
server?.name ?: stringResource(R.string.unknown)
)
)
},
text = {
Column {
Text(
text = stringResource(
id = R.string.server_context_sheet_actions_leave_confirm_eyebrow
)
)
Row(
Modifier
.fillMaxWidth()
.padding(start = 0.dp, end = 0.dp, top = 16.dp, bottom = 0.dp),
verticalAlignment = Alignment.CenterVertically
) {
Checkbox(
checked = leaveSilently,
onCheckedChange = { leaveSilently = it }
)
Text(
text = stringResource(
id = R.string.server_context_sheet_actions_leave_silently
),
modifier = Modifier.padding(start = 4.dp)
)
}
}
},
confirmButton = {
Button(
onClick = {
scope.launch {
leaveOrDeleteServer(serverId, leaveSilently)
}
showLeaveConfirmation = null
leaveSilently = false
serverContextMenuTarget = null
}
) {
Text(
text = stringResource(
id = R.string.server_context_sheet_actions_leave_confirm_yes
)
)
}
},
dismissButton = {
TextButton(
onClick = {
showLeaveConfirmation = null
leaveSilently = false
}
) {
Text(
text = stringResource(
id = R.string.server_context_sheet_actions_leave_confirm_no
)
)
}
serverContextSheetTarget = null
}
)
}
showReportServerDialog?.let { serverId ->
ReportServerDialog(
onDismiss = {
showReportServerDialog = null
serverContextMenuTarget = null
},
serverId = serverId
)
}
showInviteDialog?.let { serverId ->
val server = RevoltAPI.serverCache[serverId]
val channelId = server?.channels?.firstOrNull()
if (channelId != null) {
Dialog(
onDismissRequest = {
showInviteDialog = null
) {
ServerContextSheet(
serverId = serverContextSheetTarget!!,
onReportServer = {
reportServerTarget = serverContextSheetTarget!!
showReportServer = true
},
onHideSheet = {
serverContextSheetState.hide()
serverContextSheetTarget = null
}
) {
InviteDialog(
channelId = channelId,
onDismissRequest = {
showInviteDialog = null
}
)
}
} else {
showInviteDialog = null
serverContextMenuTarget = null
)
}
}
val scope = rememberCoroutineScope()
Row(modifier.fillMaxSize()) {
LazyColumn(
Modifier.width(64.dp),
@ -494,7 +393,7 @@ fun ChannelSideDrawer(
},
onLongClick = {
serverInList.id?.let { srvId ->
serverContextMenuTarget = srvId
serverContextSheetTarget = srvId
}
}
)) {
@ -520,115 +419,6 @@ fun ChannelSideDrawer(
}
}
DropdownMenu(
expanded = serverContextMenuTarget == serverInList.id,
onDismissRequest = { serverContextMenuTarget = null }
) {
DropdownMenuItem(
text = { Text(stringResource(R.string.server_context_sheet_actions_mark_read)) },
onClick = {
scope.launch {
serverInList.id?.let { serverId ->
RevoltAPI.unreads.markServerAsRead(serverId, sync = true)
}
}
serverContextMenuTarget = null
},
leadingIcon = {
Icon(
painter = painterResource(R.drawable.icn_mark_chat_read_24dp),
contentDescription = null
)
}
)
DropdownMenuItem(
text = { Text(stringResource(R.string.channel_info_sheet_options_invite)) },
onClick = {
serverInList.id?.let { serverId ->
showInviteDialog = serverId
}
serverContextMenuTarget = null
},
leadingIcon = {
Icon(
painter = painterResource(R.drawable.icn_add_24dp),
contentDescription = null
)
}
)
DropdownMenuItem(
text = { Text(stringResource(R.string.server_context_sheet_actions_copy_id)) },
onClick = {
serverInList.id?.let { serverId ->
clipboardManager.setText(AnnotatedString(serverId))
if (Platform.needsShowClipboardNotification()) {
Toast.makeText(
context,
context.getString(R.string.server_context_sheet_actions_copy_id_copied),
Toast.LENGTH_SHORT
).show()
}
}
serverContextMenuTarget = null
},
leadingIcon = {
Icon(
painter = painterResource(R.drawable.icn_content_copy_24dp),
contentDescription = null
)
}
)
if (serverInList.owner != RevoltAPI.selfId) {
HorizontalDivider()
DropdownMenuItem(
text = {
Text(
stringResource(R.string.server_context_sheet_actions_report),
color = MaterialTheme.colorScheme.error
)
},
onClick = {
serverInList.id?.let { serverId ->
showReportServerDialog = serverId
}
},
leadingIcon = {
Icon(
painter = painterResource(R.drawable.icn_report_24dp),
contentDescription = null,
tint = MaterialTheme.colorScheme.error
)
}
)
DropdownMenuItem(
text = {
Text(
stringResource(R.string.server_context_sheet_actions_leave),
color = MaterialTheme.colorScheme.error
)
},
onClick = {
serverInList.id?.let { serverId ->
showLeaveConfirmation = serverId
}
},
leadingIcon = {
Icon(
painter = painterResource(R.drawable.icn_door_open_24dp),
contentDescription = null,
tint = MaterialTheme.colorScheme.error
)
}
)
}
}
Box(
Modifier
.height(leftIndicatorHeight.value)
@ -840,6 +630,15 @@ fun ChannelSideDrawer(
}
}
}
if (showReportServer) {
ReportServerDialog(
onDismiss = {
showReportServer = false
},
serverId = reportServerTarget
)
}
}
@Composable