refactor: Implement bottom navigation bar

This commit introduces a bottom navigation bar to the chat interface.

Key changes include:
- Added a `Scaffold` with a `BottomAppBar` in `ChannelNavigator`.
- The `BottomAppBar` contains `NavigationBarItem`s for "Home", "Friends", and "You" (Overview).
- The "Home" destination now displays the `Sidebar`.
- Removed the tablet-aware UI logic and the dismissible navigation drawer implementation.
- Simplified `ChannelNavigator` parameters, removing `useDrawer`, `disableBackHandler`, `onEnterVoiceUI`.
- Updated screen composables (`FriendsScreen`, `NoCurrentChannelScreen`, `ChannelScreen`, `OverviewScreen`) to remove the `useDrawer` parameter and its associated logic, as the drawer is no longer directly managed by these screens.
- Removed `drawerState` parameter from `ChannelSideDrawer` and related components, as drawer state is now managed differently.
- Removed logic related to closing the drawer on item clicks within `ChannelSideDrawer`.
- Added a new `ChatRouterDestination.Home`.
- Request for `POST_NOTIFICATIONS` permission is now correctly using `Manifest.permission.POST_NOTIFICATIONS`.
This commit is contained in:
AbronStudio 2025-07-26 16:50:16 +03:30
parent 64f206fef7
commit 33296cbde1
6 changed files with 146 additions and 219 deletions

View File

@ -37,7 +37,6 @@ import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.CornerSize import androidx.compose.foundation.shape.CornerSize
import androidx.compose.material3.DrawerState
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@ -99,7 +98,6 @@ import chat.revolt.composables.screens.chat.ChannelIcon
import chat.revolt.screens.chat.ChatRouterDestination import chat.revolt.screens.chat.ChatRouterDestination
import chat.revolt.screens.chat.LocalIsConnected import chat.revolt.screens.chat.LocalIsConnected
import chat.revolt.sheets.ChannelContextSheet import chat.revolt.sheets.ChannelContextSheet
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) @OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
@Composable @Composable
@ -108,7 +106,6 @@ fun ChannelSideDrawer(
currentDestination: ChatRouterDestination, currentDestination: ChatRouterDestination,
onDestinationChanged: (ChatRouterDestination) -> Unit, onDestinationChanged: (ChatRouterDestination) -> Unit,
onLongPressAvatar: () -> Unit, onLongPressAvatar: () -> Unit,
drawerState: DrawerState?,
navigateToServer: (String) -> Unit, navigateToServer: (String) -> Unit,
onShowServerContextSheet: (String) -> Unit, onShowServerContextSheet: (String) -> Unit,
showSettingsIcon: Boolean, showSettingsIcon: Boolean,
@ -126,6 +123,7 @@ fun ChannelSideDrawer(
LaunchedEffect(currentDestination) { LaunchedEffect(currentDestination) {
if (currentDestination is ChatRouterDestination.Channel && currentServer != null) { if (currentDestination is ChatRouterDestination.Channel && currentServer != null) {
val channelIndex = categorisedChannels?.indexOfFirst { val channelIndex = categorisedChannels?.indexOfFirst {
when (it) { when (it) {
is CategorisedChannelList.Channel -> it.channel.id == currentDestination.channelId is CategorisedChannelList.Channel -> it.channel.id == currentDestination.channelId
else -> false else -> false
@ -357,9 +355,6 @@ fun ChannelSideDrawer(
.clip(CircleShape) .clip(CircleShape)
.clickable { .clickable {
serverInList.id?.let { srvId -> navigateToServer(srvId) } serverInList.id?.let { srvId -> navigateToServer(srvId) }
scope.launch {
drawerState?.close()
}
}) { }) {
val icon = serverInList.icon?.id?.let { iconId -> val icon = serverInList.icon?.id?.let { iconId ->
"$REVOLT_FILES/icons/$iconId" "$REVOLT_FILES/icons/$iconId"
@ -439,9 +434,6 @@ fun ChannelSideDrawer(
.clip(CircleShape) .clip(CircleShape)
.clickable { .clickable {
onOpenSettings() onOpenSettings()
scope.launch {
drawerState?.close()
}
} }
.size(48.dp), .size(48.dp),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
@ -577,7 +569,6 @@ fun ChannelSideDrawer(
DirectMessagesChannelListRenderer( DirectMessagesChannelListRenderer(
currentDestination, currentDestination,
onDestinationChanged, onDestinationChanged,
drawerState,
channelListState, channelListState,
onOpenChannelContextSheet = { channelContextSheetTarget = it } onOpenChannelContextSheet = { channelContextSheetTarget = it }
) )
@ -586,7 +577,6 @@ fun ChannelSideDrawer(
categorisedChannels, categorisedChannels,
currentDestination, currentDestination,
onDestinationChanged, onDestinationChanged,
drawerState,
channelListState, channelListState,
onOpenChannelContextSheet = { channelContextSheetTarget = it }, onOpenChannelContextSheet = { channelContextSheetTarget = it },
serverId = currentServer serverId = currentServer
@ -600,11 +590,9 @@ fun ChannelSideDrawer(
fun ColumnScope.DirectMessagesChannelListRenderer( fun ColumnScope.DirectMessagesChannelListRenderer(
currentDestination: ChatRouterDestination, currentDestination: ChatRouterDestination,
onDestinationChanged: (ChatRouterDestination) -> Unit, onDestinationChanged: (ChatRouterDestination) -> Unit,
drawerState: DrawerState?,
channelListState: LazyListState, channelListState: LazyListState,
onOpenChannelContextSheet: (String) -> Unit, onOpenChannelContextSheet: (String) -> Unit,
) { ) {
val scope = rememberCoroutineScope()
val dmAbleChannels = val dmAbleChannels =
RevoltAPI.channelCache.values RevoltAPI.channelCache.values
.filter { it.channelType == ChannelType.DirectMessage || it.channelType == ChannelType.Group } .filter { it.channelType == ChannelType.DirectMessage || it.channelType == ChannelType.Group }
@ -629,9 +617,6 @@ fun ColumnScope.DirectMessagesChannelListRenderer(
isCurrent = currentDestination is ChatRouterDestination.Overview, isCurrent = currentDestination is ChatRouterDestination.Overview,
onDestinationChanged = { onDestinationChanged = {
onDestinationChanged(ChatRouterDestination.Overview) onDestinationChanged(ChatRouterDestination.Overview)
scope.launch {
drawerState?.close()
}
}, },
hasUnread = false, hasUnread = false,
onOpenChannelContextSheet = {} onOpenChannelContextSheet = {}
@ -650,9 +635,6 @@ fun ColumnScope.DirectMessagesChannelListRenderer(
isCurrent = currentDestination is ChatRouterDestination.Friends, isCurrent = currentDestination is ChatRouterDestination.Friends,
onDestinationChanged = { onDestinationChanged = {
onDestinationChanged(ChatRouterDestination.Friends) onDestinationChanged(ChatRouterDestination.Friends)
scope.launch {
drawerState?.close()
}
}, },
hasUnread = FriendRequests.getIncoming().isNotEmpty(), hasUnread = FriendRequests.getIncoming().isNotEmpty(),
onOpenChannelContextSheet = {}, onOpenChannelContextSheet = {},
@ -675,9 +657,6 @@ fun ColumnScope.DirectMessagesChannelListRenderer(
currentDestination.channelId == notesChannel.id, currentDestination.channelId == notesChannel.id,
onDestinationChanged = { onDestinationChanged = {
onDestinationChanged(it) onDestinationChanged(it)
scope.launch {
drawerState?.close()
}
}, },
hasUnread = false, hasUnread = false,
onOpenChannelContextSheet = {}, onOpenChannelContextSheet = {},
@ -732,9 +711,6 @@ fun ColumnScope.DirectMessagesChannelListRenderer(
isMuted = NotificationSettingsProvider.isChannelMuted(channel.id!!, null), isMuted = NotificationSettingsProvider.isChannelMuted(channel.id!!, null),
onDestinationChanged = { dest -> onDestinationChanged = { dest ->
onDestinationChanged(dest) onDestinationChanged(dest)
scope.launch {
drawerState?.close()
}
}, },
onOpenChannelContextSheet = onOpenChannelContextSheet onOpenChannelContextSheet = onOpenChannelContextSheet
) )
@ -756,13 +732,10 @@ fun ColumnScope.ServerChannelListRenderer(
categorisedChannels: List<CategorisedChannelList>?, categorisedChannels: List<CategorisedChannelList>?,
currentDestination: ChatRouterDestination, currentDestination: ChatRouterDestination,
onDestinationChanged: (ChatRouterDestination) -> Unit, onDestinationChanged: (ChatRouterDestination) -> Unit,
drawerState: DrawerState?,
channelListState: LazyListState, channelListState: LazyListState,
onOpenChannelContextSheet: (String) -> Unit, onOpenChannelContextSheet: (String) -> Unit,
serverId: String serverId: String
) { ) {
val scope = rememberCoroutineScope()
LazyColumn( LazyColumn(
state = channelListState, state = channelListState,
verticalArrangement = Arrangement.spacedBy(4.dp), verticalArrangement = Arrangement.spacedBy(4.dp),
@ -806,11 +779,8 @@ fun ColumnScope.ServerChannelListRenderer(
else -> false else -> false
}, },
onDestinationChanged = { onDestinationChanged = { dest ->
onDestinationChanged(it) onDestinationChanged(dest)
scope.launch {
drawerState?.close()
}
}, },
hasUnread = channelOrCat.channel.lastMessageID?.let { lastMessageID -> hasUnread = channelOrCat.channel.lastMessageID?.let { lastMessageID ->
RevoltAPI.unreads.hasUnread( RevoltAPI.unreads.hasUnread(

View File

@ -1,19 +1,15 @@
package chat.revolt.screens.chat package chat.revolt.screens.chat
import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import android.util.Log import android.util.Log
import android.view.accessibility.AccessibilityManager import android.view.accessibility.AccessibilityManager
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import androidx.activity.compose.BackHandler
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
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.Row
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
@ -23,15 +19,20 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.only import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Face
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Person
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.DismissibleDrawerSheet import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.DismissibleNavigationDrawer
import androidx.compose.material3.DrawerState import androidx.compose.material3.DrawerState
import androidx.compose.material3.DrawerValue import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.material3.rememberDrawerState import androidx.compose.material3.rememberDrawerState
@ -52,8 +53,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow import androidx.compose.runtime.snapshotFlow
import androidx.compose.runtime.structuralEqualityPolicy import androidx.compose.runtime.structuralEqualityPolicy
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
@ -79,7 +78,6 @@ import chat.revolt.composables.chat.DisconnectedNotice
import chat.revolt.composables.screens.chat.drawer.ChannelSideDrawer import chat.revolt.composables.screens.chat.drawer.ChannelSideDrawer
import chat.revolt.dialogs.NotificationRationaleDialog import chat.revolt.dialogs.NotificationRationaleDialog
import chat.revolt.internals.Changelogs import chat.revolt.internals.Changelogs
import chat.revolt.internals.extensions.zero
import chat.revolt.persistence.KVStorage import chat.revolt.persistence.KVStorage
import chat.revolt.screens.chat.dialogs.safety.ReportMessageDialog import chat.revolt.screens.chat.dialogs.safety.ReportMessageDialog
import chat.revolt.screens.chat.dialogs.safety.ReportServerDialog import chat.revolt.screens.chat.dialogs.safety.ReportServerDialog
@ -111,6 +109,7 @@ import javax.inject.Inject
sealed class ChatRouterDestination { sealed class ChatRouterDestination {
data object Overview : ChatRouterDestination() data object Overview : ChatRouterDestination()
data object Friends : ChatRouterDestination() data object Friends : ChatRouterDestination()
data object Home : ChatRouterDestination()
data class Channel(val channelId: String) : ChatRouterDestination() data class Channel(val channelId: String) : ChatRouterDestination()
data class NoCurrentChannel(val serverId: String?) : ChatRouterDestination() data class NoCurrentChannel(val serverId: String?) : ChatRouterDestination()
@ -120,6 +119,7 @@ sealed class ChatRouterDestination {
is Friends -> "friends" is Friends -> "friends"
is Channel -> "channel/$channelId" is Channel -> "channel/$channelId"
is NoCurrentChannel -> "no_current_channel/$serverId" is NoCurrentChannel -> "no_current_channel/$serverId"
ChatRouterDestination.Home -> "home"
} }
} }
@ -274,7 +274,6 @@ val LocalIsConnected = compositionLocalOf(structuralEqualityPolicy()) { false }
fun ChatRouterScreen( fun ChatRouterScreen(
topNav: NavController, topNav: NavController,
windowSizeClass: WindowSizeClass, windowSizeClass: WindowSizeClass,
disableBackHandler: Boolean,
onNullifiedUser: () -> Unit, onNullifiedUser: () -> Unit,
onEnterVoiceUI: (String) -> Unit, onEnterVoiceUI: (String) -> Unit,
viewModel: ChatRouterViewModel = hiltViewModel() viewModel: ChatRouterViewModel = hiltViewModel()
@ -284,8 +283,6 @@ fun ChatRouterScreen(
val context = LocalContext.current val context = LocalContext.current
val view = LocalView.current val view = LocalView.current
var drawerWidth by remember { mutableFloatStateOf(0.0f) }
var showPlatformModDMHint by remember { mutableStateOf(false) } var showPlatformModDMHint by remember { mutableStateOf(false) }
var showStatusSheet by remember { mutableStateOf(false) } var showStatusSheet by remember { mutableStateOf(false) }
@ -736,7 +733,7 @@ fun ChatRouterScreen(
onSelected = { accepted -> onSelected = { accepted ->
if (accepted) { if (accepted) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
askNotificationsPermission.launch(android.Manifest.permission.POST_NOTIFICATIONS) askNotificationsPermission.launch(Manifest.permission.POST_NOTIFICATIONS)
} else { } else {
viewModel.setRegisterForNotifications() viewModel.setRegisterForNotifications()
} }
@ -817,128 +814,26 @@ fun ChatRouterScreen(
CompositionLocalProvider( CompositionLocalProvider(
LocalIsConnected provides (RealtimeSocket.disconnectionState == DisconnectionState.Connected) LocalIsConnected provides (RealtimeSocket.disconnectionState == DisconnectionState.Connected)
) { ) {
if (useTabletAwareUI) { ChannelNavigator(
Row { dest = viewModel.currentDestination,
DismissibleDrawerSheet( topNav = topNav,
drawerContainerColor = Color.Transparent, toggleDrawer = {
windowInsets = WindowInsets.zero toggleDrawerLambda()
) { },
Sidebar( onShowStatusSheet = {
viewModel = viewModel,
topNav = topNav,
currentServer = currentServer,
onShowStatusSheet = {
showStatusSheet = true showStatusSheet = true
}, },
onShowServerContextSheet = { onShowServerContextSheet = {
serverContextSheetTarget = it serverContextSheetTarget = it
showServerContextSheet = true showServerContextSheet = true
}, },
onShowAddServerSheet = { onShowAddServerSheet = {
showAddServerSheet = true showAddServerSheet = true
}, },
showSettingsButton = isTouchExplorationEnabled, isTouchExplorationEnabled = isTouchExplorationEnabled,
onOpenSettings = { viewModel = viewModel,
topNav.navigate("settings") currentServer = currentServer,
}, )
)
}
ChannelNavigator(
dest = viewModel.currentDestination,
topNav = topNav,
useDrawer = false,
disableBackHandler = disableBackHandler,
toggleDrawer = {
toggleDrawerLambda()
},
onEnterVoiceUI = onEnterVoiceUI,
)
}
} else {
var useSidebarGesture by remember { mutableStateOf(true) }
DismissibleNavigationDrawer(
drawerState = drawerState,
gesturesEnabled = useSidebarGesture,
drawerContent = {
DismissibleDrawerSheet(
drawerContainerColor = Color.Transparent,
windowInsets = WindowInsets.zero,
modifier = Modifier.onSizeChanged {
drawerWidth = it.width.toFloat()
}
) {
Sidebar(
viewModel = viewModel,
topNav = topNav,
currentServer = currentServer,
onShowStatusSheet = {
showStatusSheet = true
},
onShowServerContextSheet = {
serverContextSheetTarget = it
showServerContextSheet = true
},
onShowAddServerSheet = {
showAddServerSheet = true
},
showSettingsButton = isTouchExplorationEnabled,
onOpenSettings = {
topNav.navigate("settings")
},
drawerState = drawerState
)
}
},
content = {
Box(Modifier.fillMaxSize()) {
ChannelNavigator(
dest = viewModel.currentDestination,
topNav = topNav,
useDrawer = true,
disableBackHandler = disableBackHandler,
toggleDrawer = {
toggleDrawerLambda()
},
drawerState = drawerState,
drawerGestureEnabled = useSidebarGesture,
setDrawerGestureEnabled = {
useSidebarGesture = it
},
onEnterVoiceUI = onEnterVoiceUI,
)
// This is the overlay on the main content when the drawer is open
val interactionSource = remember { MutableInteractionSource() }
Box(
Modifier
.then(
if (drawerState.isOpen) {
Modifier.clickable(
interactionSource = interactionSource,
indication = null,
enabled = drawerState.isOpen,
onClick = {
scope.launch {
drawerState.close()
}
}
)
} else Modifier
)
.fillMaxSize()
.background(
MaterialTheme
.colorScheme
.surfaceContainerLowest
.copy(
alpha = (1.0f + (drawerState.currentOffset / drawerWidth)) * 0.7f
)
)
)
}
}
)
}
} }
} }
} }
@ -948,7 +843,6 @@ fun Sidebar(
viewModel: ChatRouterViewModel, viewModel: ChatRouterViewModel,
currentServer: String?, currentServer: String?,
topNav: NavController, topNav: NavController,
drawerState: DrawerState? = null,
onShowStatusSheet: () -> Unit, onShowStatusSheet: () -> Unit,
onShowServerContextSheet: (String) -> Unit, onShowServerContextSheet: (String) -> Unit,
onShowAddServerSheet: () -> Unit, onShowAddServerSheet: () -> Unit,
@ -959,7 +853,6 @@ fun Sidebar(
onDestinationChanged = viewModel::setSaveDestination, onDestinationChanged = viewModel::setSaveDestination,
currentDestination = viewModel.currentDestination, currentDestination = viewModel.currentDestination,
currentServer = currentServer, currentServer = currentServer,
drawerState = drawerState,
navigateToServer = viewModel::navigateToServer, navigateToServer = viewModel::navigateToServer,
onLongPressAvatar = onShowStatusSheet, onLongPressAvatar = onShowStatusSheet,
onShowServerContextSheet = onShowServerContextSheet, onShowServerContextSheet = onShowServerContextSheet,
@ -974,59 +867,126 @@ fun Sidebar(
fun ChannelNavigator( fun ChannelNavigator(
dest: ChatRouterDestination, dest: ChatRouterDestination,
topNav: NavController, topNav: NavController,
useDrawer: Boolean, viewModel: ChatRouterViewModel,
onShowStatusSheet: () -> Unit = {},
onShowAddServerSheet: () -> Unit = {},
onShowServerContextSheet: (String) -> Unit = {},
currentServer: String?,
toggleDrawer: () -> Unit, toggleDrawer: () -> Unit,
isTouchExplorationEnabled: Boolean,
drawerState: DrawerState? = null, drawerState: DrawerState? = null,
drawerGestureEnabled: Boolean = true,
disableBackHandler: Boolean = false,
onEnterVoiceUI: (String) -> Unit = {},
setDrawerGestureEnabled: (Boolean) -> Unit = {}, setDrawerGestureEnabled: (Boolean) -> Unit = {},
) { ) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
BackHandler(useDrawer && !disableBackHandler) { Scaffold(
toggleDrawer() modifier = Modifier.fillMaxSize(),
} bottomBar = {
BottomAppBar {
Column(Modifier.fillMaxSize()) { NavigationBarItem(
when (dest) { icon = {
is ChatRouterDestination.Overview -> { Icon(
OverviewScreen( imageVector = Icons.Default.Home,
navController = topNav, contentDescription = "Home",
useDrawer = useDrawer, )
onDrawerClicked = toggleDrawer,
)
}
is ChatRouterDestination.Friends -> {
FriendsScreen(
topNav = topNav,
useDrawer = useDrawer,
onDrawerClicked = toggleDrawer,
)
}
is ChatRouterDestination.Channel -> {
ChannelScreen(
channelId = dest.channelId,
onToggleDrawer = {
scope.launch {
if (drawerState?.isOpen == true) {
drawerState.close()
} else {
drawerState?.open()
}
}
}, },
useDrawer = useDrawer, label = {
drawerGestureEnabled = drawerGestureEnabled, Text(text = "you")
setDrawerGestureEnabled = setDrawerGestureEnabled, },
drawerIsOpen = drawerState?.isOpen == true, selected = dest is ChatRouterDestination.Home,
enabled = true,
onClick = {
viewModel.setSaveDestination(ChatRouterDestination.Home)
}
)
NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Default.Person,
contentDescription = "Friends",
)
},
label = {
Text(text = "Friends")
},
selected = dest is ChatRouterDestination.Friends,
enabled = true,
onClick = {
viewModel.setSaveDestination(ChatRouterDestination.Friends)
}
)
NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Default.Face,
contentDescription = "You",
)
},
label = {
Text(text = "you")
},
selected = dest is ChatRouterDestination.Overview,
enabled = true,
onClick = {
viewModel.setSaveDestination(ChatRouterDestination.Overview)
}
) )
} }
}
) { innerPadding ->
Column {
when (dest) {
is ChatRouterDestination.Overview -> {
OverviewScreen(
navController = topNav,
onDrawerClicked = toggleDrawer,
)
}
is ChatRouterDestination.NoCurrentChannel -> { is ChatRouterDestination.Friends -> {
NoCurrentChannelScreen(useDrawer = useDrawer, onDrawerClicked = toggleDrawer) FriendsScreen(
topNav = topNav,
onDrawerClicked = toggleDrawer,
)
}
is ChatRouterDestination.Home -> {
Row {
Sidebar(
viewModel = viewModel,
topNav = topNav,
currentServer = currentServer,
onShowStatusSheet = onShowStatusSheet,
onShowServerContextSheet = onShowServerContextSheet,
onShowAddServerSheet = onShowAddServerSheet,
showSettingsButton = isTouchExplorationEnabled,
onOpenSettings = {
topNav.navigate("settings")
},
)
}
}
is ChatRouterDestination.Channel -> {
ChannelScreen(
channelId = dest.channelId,
onToggleDrawer = {
scope.launch {
if (drawerState?.isOpen == true) {
drawerState.close()
} else {
drawerState?.open()
}
}
},
setDrawerGestureEnabled = setDrawerGestureEnabled,
drawerIsOpen = drawerState?.isOpen == true,
)
}
is ChatRouterDestination.NoCurrentChannel -> {
NoCurrentChannelScreen(onDrawerClicked = toggleDrawer)
}
} }
} }
} }

View File

@ -120,7 +120,7 @@ private fun showInvalidClipboardToast(context: Context) {
ExperimentalMaterial3ExpressiveApi::class ExperimentalMaterial3ExpressiveApi::class
) )
@Composable @Composable
fun FriendsScreen(topNav: NavController, useDrawer: Boolean, onDrawerClicked: () -> Unit) { fun FriendsScreen(topNav: NavController, useDrawer: Boolean = false, onDrawerClicked: () -> Unit) {
val clipboard = LocalClipboard.current val clipboard = LocalClipboard.current
val context = LocalContext.current val context = LocalContext.current
var overflowMenuShown by remember { mutableStateOf(false) } var overflowMenuShown by remember { mutableStateOf(false) }

View File

@ -10,8 +10,6 @@ import androidx.compose.foundation.layout.fillMaxSize
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.layout.statusBars import androidx.compose.foundation.layout.statusBars
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
@ -33,7 +31,7 @@ import chat.revolt.screens.chat.LocalIsConnected
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun NoCurrentChannelScreen(useDrawer: Boolean, onDrawerClicked: () -> Unit) { fun NoCurrentChannelScreen(useDrawer: Boolean = false, onDrawerClicked: () -> Unit) {
Scaffold( Scaffold(
topBar = { topBar = {
Column { Column {

View File

@ -68,7 +68,7 @@ import io.sentry.Sentry
@Composable @Composable
fun OverviewScreen( fun OverviewScreen(
navController: NavController, navController: NavController,
useDrawer: Boolean, useDrawer: Boolean = false,
onDrawerClicked: () -> Unit, onDrawerClicked: () -> Unit,
includePadding: Boolean = true includePadding: Boolean = true
) { ) {

View File

@ -190,9 +190,8 @@ private const val NOT_ENOUGH_SPACE_FOR_PANES_THRESHOLD = 500
fun ChannelScreen( fun ChannelScreen(
channelId: String, channelId: String,
onToggleDrawer: () -> Unit, onToggleDrawer: () -> Unit,
useDrawer: Boolean, useDrawer: Boolean = false,
useBackButton: Boolean = false, useBackButton: Boolean = false,
drawerGestureEnabled: Boolean = true,
setDrawerGestureEnabled: (Boolean) -> Unit = {}, setDrawerGestureEnabled: (Boolean) -> Unit = {},
drawerIsOpen: Boolean = false, drawerIsOpen: Boolean = false,
backButtonAction: (() -> Unit)? = null, backButtonAction: (() -> Unit)? = null,
@ -347,7 +346,7 @@ fun ChannelScreen(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
contentValues contentValues
) )
} catch (e: Exception) { } catch (_: Exception) {
Toast.makeText( Toast.makeText(
context, context,
context.getString( context.getString(
@ -363,7 +362,7 @@ fun ChannelScreen(
capturedPhotoUri.value?.let { uri -> capturedPhotoUri.value?.let { uri ->
pickCameraLauncher.launch(uri) pickCameraLauncher.launch(uri)
} }
} catch (e: Exception) { } catch (_: Exception) {
Toast.makeText( Toast.makeText(
context, context,
context.getString( context.getString(