|
|
@@ -11,19 +11,12 @@ package org.mjdev.tvapp.base.ui.components.navigation
|
|
|
import android.annotation.SuppressLint
|
|
|
import androidx.compose.foundation.background
|
|
|
import androidx.compose.foundation.border
|
|
|
-import androidx.compose.foundation.layout.Arrangement
|
|
|
-import androidx.compose.foundation.layout.Column
|
|
|
import androidx.compose.foundation.layout.fillMaxHeight
|
|
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
|
-import androidx.compose.material.icons.Icons
|
|
|
-import androidx.compose.material.icons.outlined.Search
|
|
|
-import androidx.compose.material.icons.outlined.Settings
|
|
|
import androidx.compose.runtime.Composable
|
|
|
-import androidx.compose.runtime.mutableIntStateOf
|
|
|
-import androidx.compose.runtime.remember
|
|
|
-import androidx.compose.ui.Alignment
|
|
|
import androidx.compose.ui.Modifier
|
|
|
import androidx.compose.ui.graphics.Color
|
|
|
+import androidx.compose.ui.graphics.Shape
|
|
|
import androidx.compose.ui.unit.Dp
|
|
|
import androidx.compose.ui.unit.dp
|
|
|
import androidx.tv.material3.DrawerValue
|
|
|
@@ -32,158 +25,53 @@ import androidx.tv.material3.NavigationDrawer
|
|
|
import androidx.tv.material3.rememberDrawerState
|
|
|
import org.mjdev.tvapp.base.annotations.TvPreview
|
|
|
import org.mjdev.tvapp.base.extensions.ComposeExt.isEditMode
|
|
|
-import org.mjdev.tvapp.base.navigation.MenuItem
|
|
|
-import org.mjdev.tvapp.base.navigation.NavHostControllerEx
|
|
|
+import org.mjdev.tvapp.base.extensions.NavExt.rememberNavControllerEx
|
|
|
|
|
|
-const val SETTINGS_ITEM = 65535
|
|
|
-const val SEARCH_ITEM = 65534
|
|
|
-
|
|
|
-@Suppress("LocalVariableName")
|
|
|
@SuppressLint("AutoboxingStateValueProperty")
|
|
|
@OptIn(ExperimentalTvMaterial3Api::class)
|
|
|
@TvPreview
|
|
|
@Composable
|
|
|
fun Navigation(
|
|
|
modifier: Modifier = Modifier,
|
|
|
- navController: NavHostControllerEx? = null,
|
|
|
- items: List<MenuItem> = listOf(),
|
|
|
- backgroundColor: Color = Color.DarkGray,
|
|
|
- roundSize: Dp = 8.dp,
|
|
|
+ navController: NavHostControllerEx = rememberNavControllerEx(),
|
|
|
+ navigationState: NavigationState = rememberNavigationState(
|
|
|
+ navController = navController,
|
|
|
+ drawerState = rememberDrawerState(
|
|
|
+ initialValue = DrawerValue.Open
|
|
|
+ )
|
|
|
+ ),
|
|
|
+ backgroundColor: Color = Color(0xff202020),
|
|
|
+ roundCornerSize: Dp = 8.dp,
|
|
|
borderSize: Dp = 0.dp,
|
|
|
- borderColor: Color = Color.White,
|
|
|
- showSearch: Boolean = true,
|
|
|
- showSettings: Boolean = true,
|
|
|
- searchArrangement: Arrangement.Vertical = Arrangement.Top,
|
|
|
- settingsArrangement: Arrangement.Vertical = Arrangement.Bottom,
|
|
|
- onSettingsItemFocused: () -> Unit = {},
|
|
|
- onSearchItemFocused: () -> Unit = {},
|
|
|
- onSettingsItemClicked: () -> Unit = {},
|
|
|
- onSearchItemClicked: () -> Unit = {},
|
|
|
- onDrawerItemClick: (id: Int) -> Unit = {},
|
|
|
- onDrawerItemFocused: (id: Int) -> Unit = {},
|
|
|
- content: @Composable () -> Unit = {}
|
|
|
+ borderColor: Color = Color.Transparent,
|
|
|
+ shape: Shape = RoundedCornerShape(roundCornerSize),
|
|
|
+ content: @Composable () -> Unit = {},
|
|
|
+ menuItems: List<MenuItem> = listOf()
|
|
|
) {
|
|
|
|
|
|
val isEdit = isEditMode()
|
|
|
- val drawerState = rememberDrawerState(if (isEdit) DrawerValue.Open else DrawerValue.Closed)
|
|
|
- val focused = remember { mutableIntStateOf(-1) }
|
|
|
-
|
|
|
- val _onDrawerItemClick: (id: Int) -> Unit = { id ->
|
|
|
- when (id) {
|
|
|
- SETTINGS_ITEM -> onSettingsItemClicked()
|
|
|
- SEARCH_ITEM -> onSearchItemClicked()
|
|
|
- else -> items[id].let { menuItem ->
|
|
|
- navController?.onMenuItemClick(menuItem)
|
|
|
- onDrawerItemClick(id)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- val _onDrawerItemFocus: (id: Int) -> Unit = { id ->
|
|
|
- when (id) {
|
|
|
- SETTINGS_ITEM -> onSettingsItemFocused()
|
|
|
- SEARCH_ITEM -> onSearchItemFocused()
|
|
|
- else -> items[id].let { menuItem ->
|
|
|
- navController?.onMenuItemClick(menuItem)
|
|
|
- onDrawerItemFocused(id)
|
|
|
+ if (isEdit) navigationState.openDrawer()
|
|
|
+ navController.addMenuItem(*menuItems.toTypedArray())
|
|
|
+
|
|
|
+ if (navController.menuState.value) {
|
|
|
+ NavigationDrawer(
|
|
|
+ modifier = modifier
|
|
|
+ .fillMaxHeight()
|
|
|
+ .background(backgroundColor, shape)
|
|
|
+ .border(borderSize, borderColor, shape),
|
|
|
+ content = content,
|
|
|
+ drawerState = navigationState.drawerState,
|
|
|
+ drawerContent = { state ->
|
|
|
+ NavDrawerContent(
|
|
|
+ backgroundColor = backgroundColor,
|
|
|
+ navController = navController,
|
|
|
+ navigationState = navigationState,
|
|
|
+ )
|
|
|
+ navigationState.drawerState.setValue(state)
|
|
|
}
|
|
|
- }
|
|
|
+ )
|
|
|
+ } else {
|
|
|
+ content()
|
|
|
}
|
|
|
|
|
|
- NavigationDrawer(
|
|
|
- modifier = modifier
|
|
|
- .fillMaxHeight()
|
|
|
- .background(backgroundColor)
|
|
|
- .apply {
|
|
|
- if (borderSize > 0.dp) {
|
|
|
- border(borderSize, borderColor, RoundedCornerShape(roundSize))
|
|
|
- }
|
|
|
- },
|
|
|
- content = content,
|
|
|
- drawerState = drawerState,
|
|
|
- drawerContent = { state ->
|
|
|
-
|
|
|
- focused.value.apply {
|
|
|
-
|
|
|
- if (showSettings) {
|
|
|
- Column(
|
|
|
- modifier = Modifier.fillMaxHeight(),
|
|
|
- verticalArrangement = settingsArrangement,
|
|
|
- horizontalAlignment = Alignment.Start,
|
|
|
- ) {
|
|
|
-
|
|
|
- NavigationRow(
|
|
|
- id = SETTINGS_ITEM,
|
|
|
- drawerValue = state,
|
|
|
- icon = Icons.Outlined.Settings,
|
|
|
- text = "Settings",
|
|
|
- onFocus = { id ->
|
|
|
- drawerState.setValue(DrawerValue.Open)
|
|
|
- focused.value = id
|
|
|
- _onDrawerItemFocus(id)
|
|
|
- },
|
|
|
- onClick = { id ->
|
|
|
- _onDrawerItemClick(id)
|
|
|
- }
|
|
|
- )
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (showSearch) {
|
|
|
- Column(
|
|
|
- modifier = Modifier
|
|
|
- .fillMaxHeight(),
|
|
|
- verticalArrangement = searchArrangement,
|
|
|
- horizontalAlignment = Alignment.Start,
|
|
|
- ) {
|
|
|
-
|
|
|
- NavigationRow(
|
|
|
- id = SEARCH_ITEM,
|
|
|
- drawerValue = state,
|
|
|
- icon = Icons.Outlined.Search,
|
|
|
- text = "Search",
|
|
|
- onFocus = { id ->
|
|
|
- drawerState.setValue(DrawerValue.Open)
|
|
|
- focused.value = id
|
|
|
- _onDrawerItemFocus(id)
|
|
|
- },
|
|
|
- onClick = { id ->
|
|
|
- _onDrawerItemClick(id)
|
|
|
- }
|
|
|
- )
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Column(
|
|
|
- modifier = Modifier
|
|
|
- .fillMaxHeight(),
|
|
|
- verticalArrangement = Arrangement.Center,
|
|
|
- horizontalAlignment = Alignment.Start,
|
|
|
- ) {
|
|
|
-
|
|
|
- items.forEachIndexed { idx, menuItem ->
|
|
|
- NavigationRow(
|
|
|
- id = idx,
|
|
|
- drawerValue = state,
|
|
|
- text = menuItem.menuText,
|
|
|
- icon = menuItem.menuIcon,
|
|
|
- onFocus = { id ->
|
|
|
- drawerState.setValue(DrawerValue.Open)
|
|
|
- focused.value = id
|
|
|
- _onDrawerItemFocus(id)
|
|
|
- },
|
|
|
- onClick = { id ->
|
|
|
- _onDrawerItemClick(id)
|
|
|
- }
|
|
|
- )
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
- )
|
|
|
-
|
|
|
}
|