mirror of
https://github.com/Suwayomi/TachideskJUI.git
synced 2026-01-30 07:24:08 +01:00
Implement searchbar + initial extension search
This commit is contained in:
@@ -6,23 +6,40 @@
|
||||
|
||||
package ca.gosyer.ui.base.components
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.material.AppBarDefaults
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TopAppBar
|
||||
import androidx.compose.material.contentColorFor
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
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.RectangleShape
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import ca.gosyer.ui.main.Route
|
||||
import com.github.zsoltk.compose.router.BackStack
|
||||
import compose.icons.FontAwesomeIcons
|
||||
@@ -36,19 +53,50 @@ fun Toolbar(
|
||||
closable: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
actions: @Composable RowScope.() -> Unit = {},
|
||||
backgroundColor: Color = MaterialTheme.colors.primary, // CustomColors.current.bars,
|
||||
contentColor: Color = MaterialTheme.colors.onPrimary, // CustomColors.current.onBars,
|
||||
backgroundColor: Color = MaterialTheme.colors.surface, // CustomColors.current.bars,
|
||||
contentColor: Color = contentColorFor(backgroundColor), // CustomColors.current.onBars,
|
||||
elevation: Dp = AppBarDefaults.TopAppBarElevation,
|
||||
search: ((String) -> Unit)? = null
|
||||
) {
|
||||
val searchText = remember { mutableStateOf("") }
|
||||
Surface(Modifier.fillMaxWidth().height(32.dp), elevation = 2.dp) {
|
||||
TopAppBar(
|
||||
{
|
||||
Text(name)
|
||||
},
|
||||
modifier,
|
||||
actions = @Composable {
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
elevation = elevation,
|
||||
shape = RectangleShape,
|
||||
color = backgroundColor,
|
||||
contentColor = contentColor
|
||||
) {
|
||||
Row(
|
||||
Modifier.fillMaxWidth().padding(AppBarDefaults.ContentPadding).height(56.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(name, fontSize = 24.sp)
|
||||
if (search != null) {
|
||||
Card(
|
||||
Modifier.fillMaxHeight()
|
||||
.width(300.dp)
|
||||
.padding(8.dp),
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
elevation = 2.dp,
|
||||
border = BorderStroke(1.dp, MaterialTheme.colors.primary)
|
||||
) {
|
||||
Box(Modifier.fillMaxSize().padding(8.dp), Alignment.CenterStart) {
|
||||
BasicTextField(
|
||||
searchText.value,
|
||||
onValueChange = {
|
||||
searchText.value = it
|
||||
search(it)
|
||||
},
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
textStyle = TextStyle(contentColor, 18.sp),
|
||||
cursorBrush = SolidColor(contentColor.copy(alpha = 0.50F))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Row {
|
||||
actions()
|
||||
if (closable) {
|
||||
IconButton(
|
||||
@@ -56,34 +104,10 @@ fun Toolbar(
|
||||
router?.pop()
|
||||
}
|
||||
) {
|
||||
Icon(FontAwesomeIcons.Regular.WindowClose, "close")
|
||||
Icon(FontAwesomeIcons.Regular.WindowClose, "close", Modifier.size(52.dp))
|
||||
}
|
||||
}
|
||||
},
|
||||
backgroundColor = backgroundColor,
|
||||
contentColor = contentColor,
|
||||
elevation = elevation
|
||||
)
|
||||
/*Row(Modifier.fillMaxSize(), horizontalArrangement = Arrangement.SpaceBetween) {
|
||||
Text(name, fontSize = 24.sp)
|
||||
if (search != null) {
|
||||
BasicTextField(
|
||||
searchText.value,
|
||||
onValueChange = {
|
||||
searchText.value = it
|
||||
search(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
if (closable) {
|
||||
IconButton(
|
||||
onClick = {
|
||||
router?.pop()
|
||||
}
|
||||
) {
|
||||
Icon(FontAwesomeIcons.Regular.WindowClose, "close", Modifier.size(32.dp))
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import androidx.compose.ui.unit.sp
|
||||
import ca.gosyer.data.models.Extension
|
||||
import ca.gosyer.ui.base.components.KtorImage
|
||||
import ca.gosyer.ui.base.components.LoadingScreen
|
||||
import ca.gosyer.ui.base.components.Toolbar
|
||||
import ca.gosyer.ui.base.vm.viewModel
|
||||
import ca.gosyer.util.compose.ThemedWindow
|
||||
|
||||
@@ -61,7 +62,7 @@ fun ExtensionsMenu() {
|
||||
val serverUrl by vm.serverUrl.collectAsState()
|
||||
|
||||
Box(Modifier.fillMaxSize().background(MaterialTheme.colors.background)) {
|
||||
if (extensions.isEmpty()) {
|
||||
if (isLoading) {
|
||||
LoadingScreen(isLoading)
|
||||
} else {
|
||||
val state = rememberLazyListState()
|
||||
@@ -69,6 +70,15 @@ fun ExtensionsMenu() {
|
||||
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
LazyColumn(Modifier.fillMaxSize().padding(end = 12.dp), state) {
|
||||
item {
|
||||
Toolbar(
|
||||
"Extensions",
|
||||
closable = false,
|
||||
search = {
|
||||
vm.search(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
items(extensions) { extension ->
|
||||
ExtensionItem(
|
||||
extension,
|
||||
@@ -87,7 +97,7 @@ fun ExtensionsMenu() {
|
||||
modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(),
|
||||
adapter = rememberScrollbarAdapter(
|
||||
scrollState = state,
|
||||
itemCount = itemCount,
|
||||
itemCount = itemCount + 1, // Plus toolbar,
|
||||
averageItemSize = 37.dp // TextBox height + Spacer height
|
||||
)
|
||||
)
|
||||
|
||||
@@ -27,6 +27,8 @@ class ExtensionsMenuViewModel @Inject constructor(
|
||||
|
||||
val serverUrl = serverPreferences.server().stateIn(scope)
|
||||
|
||||
private lateinit var extensionList: List<Extension>
|
||||
|
||||
private val _extensions = MutableStateFlow(emptyList<Extension>())
|
||||
val extensions = _extensions.asStateFlow()
|
||||
|
||||
@@ -43,8 +45,8 @@ class ExtensionsMenuViewModel @Inject constructor(
|
||||
try {
|
||||
_isLoading.value = true
|
||||
val enabledLangs = extensionPreferences.languages().get()
|
||||
val extensions = extensionHandler.getExtensionList()
|
||||
_extensions.value = extensions.filter { it.lang in enabledLangs }.sortedWith(compareBy({ it.lang }, { it.pkgName }))
|
||||
extensionList = extensionHandler.getExtensionList()
|
||||
_extensions.value = extensionList.filter { it.lang in enabledLangs }.sortedWith(compareBy({ it.lang }, { it.pkgName }))
|
||||
} catch (e: Exception) {
|
||||
if (e is CancellationException) throw e
|
||||
} finally {
|
||||
@@ -75,4 +77,17 @@ class ExtensionsMenuViewModel @Inject constructor(
|
||||
getExtensions()
|
||||
}
|
||||
}
|
||||
|
||||
fun search(searchQuery: String) {
|
||||
if (searchQuery.isBlank()) {
|
||||
_extensions.value = extensionList
|
||||
} else {
|
||||
val queries = searchQuery.split(" ")
|
||||
val extensions = extensionList.toMutableList()
|
||||
queries.forEach { query ->
|
||||
extensions.removeIf { !it.name.contains(query, true) }
|
||||
}
|
||||
_extensions.value = extensions.toList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user