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:
parent
64f206fef7
commit
33296cbde1
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) }
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue