feat(app): add navigation to License screen

This commit is contained in:
Anthony 2024-06-11 23:45:32 +02:00
parent 4cfee38bf4
commit 1b94c0a694
2 changed files with 85 additions and 21 deletions

View File

@ -3,6 +3,7 @@ package component
import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedContent
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
@ -10,26 +11,31 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Clear import androidx.compose.material.icons.filled.Clear
import androidx.compose.material.icons.filled.Menu import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.Place
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.isTraversalGroup import androidx.compose.ui.semantics.isTraversalGroup
import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.traversalIndex import androidx.compose.ui.semantics.traversalIndex
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import data.ENumber import data.ENumber
import tab.Licenses
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun Search(eNumbers: List<ENumber>) { fun Search(eNumbers: List<ENumber>) {
var text by rememberSaveable { mutableStateOf("") } var text by rememberSaveable { mutableStateOf("") }
var expanded by rememberSaveable { mutableStateOf(false) } var expanded by rememberSaveable { mutableStateOf(false) }
val menuExpanded = remember { mutableStateOf(false) }
Column ( Column (
Modifier Modifier
@ -48,30 +54,35 @@ fun Search(eNumbers: List<ENumber>) {
active = expanded, active = expanded,
placeholder = { Text("Search E Numbers") }, placeholder = { Text("Search E Numbers") },
leadingIcon = { leadingIcon = {
IconButton(onClick = { IconButton(
if (expanded) { enabled = expanded,
expanded = false onClick = { if (expanded) expanded = false }
} else { ) {
/* TODO add navigation menu functionality */
}
}) {
AnimatedContent( AnimatedContent(
targetState = expanded, targetState = expanded,
) { targetExpanded -> ) { targetExpanded ->
if (targetExpanded) { if (targetExpanded) {
Icon(Icons.AutoMirrored.Filled.ArrowBack, "Exit Search") Icon(Icons.AutoMirrored.Filled.ArrowBack, "Exit Search")
} else { } else {
Icon(Icons.Filled.Menu, "Navigation Menu") Icon(Icons.Filled.Search, "Navigation Menu")
} }
} }
} }
}, },
trailingIcon = { trailingIcon = {
if (text.isNotBlank()) { Row {
if (text.isNotEmpty()) {
IconButton(onClick = { text = "" }) { IconButton(onClick = { text = "" }) {
Icon(imageVector = Icons.Filled.Clear, contentDescription = "Clear Search") Icon(imageVector = Icons.Filled.Clear, contentDescription = "Clear Search")
} }
} }
if (!expanded) {
IconButton(onClick = { menuExpanded.value = !menuExpanded.value }) {
Icon(imageVector = Icons.Filled.MoreVert, contentDescription = "Dropdown Menu")
}
OptionsMenu(menuExpanded)
}
}
} }
) { ) {
Column(Modifier.verticalScroll(rememberScrollState())) { Column(Modifier.verticalScroll(rememberScrollState())) {
@ -92,6 +103,32 @@ fun Search(eNumbers: List<ENumber>) {
} }
} }
@Composable
private fun OptionsMenu(expanded: MutableState<Boolean>) {
val navigator = LocalNavigator.currentOrThrow
DropdownMenu(
expanded = expanded.value,
onDismissRequest = { expanded.value = false },
) {
DropdownMenuItem(
text = { Text("Settings") },
onClick = { /* TODO open settings screen */ },
leadingIcon = { Icon(imageVector = Icons.Outlined.Settings, contentDescription = "Open settings") }
)
DropdownMenuItem(
text = { Text("About") },
onClick = { /* TODO open about screen */ },
leadingIcon = { Icon(imageVector = Icons.Outlined.Place, contentDescription = "Information about the application") }
)
DropdownMenuItem(
text = { Text("Licenses") },
onClick = { navigator.push(Licenses) },
leadingIcon = { Icon(imageVector = Icons.Outlined.Info, contentDescription = "Information about Licenses") }
)
}
}
private fun searchSuggestion(query: String, eNumbers: List<ENumber>): List<ENumber> { private fun searchSuggestion(query: String, eNumbers: List<ENumber>): List<ENumber> {
if (query.isEmpty()) { if (query.isEmpty()) {
return eNumbers return eNumbers

View File

@ -1,9 +1,16 @@
package tab package tab
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.ExperimentalResourceApi
import veganenumbers.composeapp.generated.resources.Res.readBytes import veganenumbers.composeapp.generated.resources.Res.readBytes
@ -19,7 +26,7 @@ object Licenses : Screen {
return json return json
} }
@OptIn(ExperimentalResourceApi::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
override fun Content() { override fun Content() {
var licenses by remember{ mutableStateOf("") } var licenses by remember{ mutableStateOf("") }
@ -28,9 +35,29 @@ object Licenses : Screen {
licenses = loadLicenses() licenses = loadLicenses()
} }
val navigator = LocalNavigator.currentOrThrow
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
Scaffold (
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
TopAppBar(
title = { Text("Licenses") },
navigationIcon = {
IconButton(onClick = { navigator.pop() }) {
Icon(imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Go back to main app")
}
},
scrollBehavior = scrollBehavior
)
},
) {
LibrariesContainer( LibrariesContainer(
licenses, licenses,
Modifier.fillMaxSize() Modifier
.padding(it)
.fillMaxSize()
) )
} }
}
} }