mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Use LazyColumn for all nav drawer items
This commit is contained in:
parent
ffc704bdce
commit
46073cbd74
2 changed files with 117 additions and 66 deletions
|
|
@ -5,6 +5,7 @@ import android.media.AudioManager
|
|||
import android.view.KeyEvent
|
||||
import androidx.compose.foundation.MarqueeAnimationMode
|
||||
import androidx.compose.foundation.basicMarquee
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
|
|
@ -17,6 +18,8 @@ import androidx.compose.ui.focus.FocusRequester
|
|||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.media3.common.Player
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
|
@ -26,6 +29,7 @@ import timber.log.Timber
|
|||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.math.min
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
|
|
@ -199,3 +203,29 @@ inline fun <T : Collection<*>, R> T.letNotEmpty(block: (T) -> R): R? {
|
|||
}
|
||||
return if (this.isNotEmpty()) block(this) else null
|
||||
}
|
||||
|
||||
// Adapted from https://stackoverflow.com/a/69196765
|
||||
fun Arrangement.spacedByWithFooter(space: Dp) =
|
||||
object : Arrangement.Vertical {
|
||||
override val spacing = space
|
||||
|
||||
override fun Density.arrange(
|
||||
totalSize: Int,
|
||||
sizes: IntArray,
|
||||
outPositions: IntArray,
|
||||
) {
|
||||
if (sizes.isEmpty()) return
|
||||
val spacePx = space.roundToPx()
|
||||
|
||||
var occupied = 0
|
||||
sizes.forEachIndexed { index, size ->
|
||||
if (index == sizes.lastIndex) {
|
||||
outPositions[index] = totalSize - size
|
||||
} else {
|
||||
outPositions[index] = min(occupied, totalSize - size)
|
||||
}
|
||||
val lastSpace = min(spacePx, totalSize - outPositions[index] - size)
|
||||
occupied = outPositions[index] + size + lastSpace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
|
|||
import androidx.compose.foundation.interaction.collectIsFocusedAsState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
|
|
@ -27,8 +26,8 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusProperties
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.focus.focusRestorer
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
|
|
@ -60,6 +59,9 @@ import com.github.damontecres.dolphin.data.ServerRepository
|
|||
import com.github.damontecres.dolphin.data.model.BaseItem
|
||||
import com.github.damontecres.dolphin.preferences.UserPreferences
|
||||
import com.github.damontecres.dolphin.ui.FontAwesome
|
||||
import com.github.damontecres.dolphin.ui.ifElse
|
||||
import com.github.damontecres.dolphin.ui.spacedByWithFooter
|
||||
import com.github.damontecres.dolphin.ui.tryRequestFocus
|
||||
import com.github.damontecres.dolphin.util.ExceptionHandler
|
||||
import com.github.damontecres.dolphin.util.supportedCollectionTypes
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
|
|
@ -124,6 +126,7 @@ fun NavDrawer(
|
|||
}
|
||||
val libraries by viewModel.libraries.observeAsState(listOf())
|
||||
val selectedIndex by viewModel.selectedIndex.observeAsState(-1)
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
|
||||
NavigationDrawer(
|
||||
modifier =
|
||||
|
|
@ -132,76 +135,94 @@ fun NavDrawer(
|
|||
drawerState = drawerState,
|
||||
drawerContent = {
|
||||
ProvideTextStyle(MaterialTheme.typography.labelMedium) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
LazyColumn(
|
||||
state = listState,
|
||||
contentPadding = PaddingValues(0.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedByWithFooter(8.dp),
|
||||
modifier =
|
||||
Modifier
|
||||
.focusGroup()
|
||||
// TODO fix focus restorer
|
||||
.focusRestorer()
|
||||
.fillMaxHeight()
|
||||
.focusProperties {
|
||||
onEnter = {
|
||||
focusRequester.tryRequestFocus()
|
||||
}
|
||||
}.fillMaxHeight()
|
||||
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp)),
|
||||
) {
|
||||
IconNavItem(
|
||||
text = user?.name ?: "",
|
||||
subtext = server?.name ?: server?.url,
|
||||
icon = Icons.Default.AccountCircle,
|
||||
selected = false,
|
||||
onClick = {
|
||||
navigationManager.navigateTo(Destination.UserList)
|
||||
},
|
||||
)
|
||||
IconNavItem(
|
||||
text = "Search",
|
||||
icon = Icons.Default.Search,
|
||||
selected = selectedIndex == -2,
|
||||
onClick = {
|
||||
viewModel.setIndex(-2)
|
||||
navigationManager.navigateToFromDrawer(Destination.Search)
|
||||
},
|
||||
)
|
||||
IconNavItem(
|
||||
text = "Home",
|
||||
icon = Icons.Default.Home,
|
||||
selected = selectedIndex == -1,
|
||||
onClick = {
|
||||
viewModel.setIndex(-1)
|
||||
if (destination is Destination.Main) {
|
||||
navigationManager.reloadHome()
|
||||
} else {
|
||||
navigationManager.goToHome()
|
||||
}
|
||||
},
|
||||
)
|
||||
LazyColumn(
|
||||
state = listState,
|
||||
contentPadding = PaddingValues(0.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
modifier =
|
||||
Modifier
|
||||
.weight(1f),
|
||||
) {
|
||||
itemsIndexed(libraries) { index, it ->
|
||||
LibraryNavItem(
|
||||
library = it,
|
||||
selected = selectedIndex == index,
|
||||
onClick = {
|
||||
viewModel.setIndex(index)
|
||||
navigationManager.navigateToFromDrawer(it.destination())
|
||||
},
|
||||
)
|
||||
}
|
||||
item {
|
||||
IconNavItem(
|
||||
text = user?.name ?: "",
|
||||
subtext = server?.name ?: server?.url,
|
||||
icon = Icons.Default.AccountCircle,
|
||||
selected = false,
|
||||
onClick = {
|
||||
navigationManager.navigateTo(Destination.UserList)
|
||||
},
|
||||
)
|
||||
}
|
||||
item {
|
||||
IconNavItem(
|
||||
text = "Search",
|
||||
icon = Icons.Default.Search,
|
||||
selected = selectedIndex == -2,
|
||||
onClick = {
|
||||
viewModel.setIndex(-2)
|
||||
navigationManager.navigateToFromDrawer(Destination.Search)
|
||||
},
|
||||
modifier =
|
||||
Modifier.ifElse(
|
||||
selectedIndex == -2,
|
||||
Modifier.focusRequester(focusRequester),
|
||||
),
|
||||
)
|
||||
}
|
||||
item {
|
||||
IconNavItem(
|
||||
text = "Home",
|
||||
icon = Icons.Default.Home,
|
||||
selected = selectedIndex == -1,
|
||||
onClick = {
|
||||
viewModel.setIndex(-1)
|
||||
if (destination is Destination.Main) {
|
||||
navigationManager.reloadHome()
|
||||
} else {
|
||||
navigationManager.goToHome()
|
||||
}
|
||||
},
|
||||
modifier =
|
||||
Modifier.ifElse(
|
||||
selectedIndex == -1,
|
||||
Modifier.focusRequester(focusRequester),
|
||||
),
|
||||
)
|
||||
}
|
||||
itemsIndexed(libraries) { index, it ->
|
||||
LibraryNavItem(
|
||||
library = it,
|
||||
selected = selectedIndex == index,
|
||||
onClick = {
|
||||
viewModel.setIndex(index)
|
||||
navigationManager.navigateToFromDrawer(it.destination())
|
||||
},
|
||||
modifier =
|
||||
Modifier.ifElse(
|
||||
selectedIndex == index,
|
||||
Modifier.focusRequester(focusRequester),
|
||||
),
|
||||
)
|
||||
}
|
||||
item {
|
||||
IconNavItem(
|
||||
text = "Settings",
|
||||
icon = Icons.Default.Settings,
|
||||
selected = false,
|
||||
onClick = {
|
||||
navigationManager.navigateTo(Destination.Settings)
|
||||
},
|
||||
modifier = Modifier,
|
||||
)
|
||||
}
|
||||
IconNavItem(
|
||||
text = "Settings",
|
||||
icon = Icons.Default.Settings,
|
||||
selected = false,
|
||||
onClick = {
|
||||
navigationManager.navigateTo(Destination.Settings)
|
||||
},
|
||||
modifier = Modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue