queryeditor wip
This commit is contained in:
@@ -79,7 +79,7 @@ dependencies {
|
||||
implementation "androidx.biometric:biometric:1.1.0"
|
||||
implementation "androidx.work:work-runtime-ktx:2.9.0"
|
||||
|
||||
implementation platform("androidx.compose:compose-bom:2024.02.00")
|
||||
implementation platform("androidx.compose:compose-bom:2024.02.01")
|
||||
|
||||
implementation "androidx.compose.material3:material3"
|
||||
implementation "androidx.compose.material3:material3-window-size-class"
|
||||
@@ -87,7 +87,7 @@ dependencies {
|
||||
implementation 'androidx.compose.ui:ui'
|
||||
implementation 'androidx.compose.ui:ui-tooling-preview'
|
||||
debugImplementation 'androidx.compose.ui:ui-tooling'
|
||||
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
|
||||
androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.6.1'
|
||||
debugImplementation 'androidx.compose.ui:ui-test-manifest'
|
||||
implementation 'androidx.compose.material:material-icons-extended'
|
||||
implementation 'androidx.activity:activity-compose:1.8.2'
|
||||
|
||||
@@ -11,8 +11,6 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import xyz.quaver.pupil.hitomi.max_node_size
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.IntBuffer
|
||||
|
||||
@@ -1,8 +1,35 @@
|
||||
package xyz.quaver.pupil.networking
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
|
||||
class SearchQueryPreviewParameterProvider: PreviewParameterProvider<SearchQuery> {
|
||||
override val values = sequenceOf(
|
||||
SearchQuery.And(listOf(
|
||||
SearchQuery.Or(listOf(
|
||||
SearchQuery.And(listOf(
|
||||
SearchQuery.Tag("language", "korean"),
|
||||
SearchQuery.Tag("female", "unusual pupil"),
|
||||
SearchQuery.Tag("female", "collar")
|
||||
)),
|
||||
SearchQuery.And(listOf(
|
||||
SearchQuery.Tag("language", "japanese"),
|
||||
SearchQuery.Tag("female", "unusual pupil"),
|
||||
SearchQuery.Tag("female", "collar")
|
||||
))
|
||||
)),
|
||||
SearchQuery.Not(
|
||||
SearchQuery.And(listOf(
|
||||
SearchQuery.Tag("male", "yaoi"),
|
||||
SearchQuery.Tag("group", "zenmai kourogi")
|
||||
))
|
||||
)
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
sealed interface SearchQuery {
|
||||
data class Tag(
|
||||
val namespace: String?,
|
||||
val namespace: String? = null,
|
||||
val tag: String
|
||||
): SearchQuery, TagLike {
|
||||
companion object {
|
||||
|
||||
@@ -1,38 +1,63 @@
|
||||
package xyz.quaver.pupil.ui.composable
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.horizontalScroll
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxScope
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawingPadding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.AddCircleOutline
|
||||
import androidx.compose.material.icons.filled.Book
|
||||
import androidx.compose.material.icons.filled.Brush
|
||||
import androidx.compose.material.icons.filled.Face
|
||||
import androidx.compose.material.icons.filled.Female
|
||||
import androidx.compose.material.icons.filled.Folder
|
||||
import androidx.compose.material.icons.filled.Group
|
||||
import androidx.compose.material.icons.filled.LocalOffer
|
||||
import androidx.compose.material.icons.filled.Male
|
||||
import androidx.compose.material.icons.filled.RemoveCircleOutline
|
||||
import androidx.compose.material.icons.filled.Translate
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardColors
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
@@ -41,8 +66,11 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.window.layout.DisplayFeature
|
||||
@@ -51,8 +79,154 @@ import com.google.accompanist.adaptive.TwoPane
|
||||
import xyz.quaver.pupil.R
|
||||
import xyz.quaver.pupil.networking.GalleryInfo
|
||||
import xyz.quaver.pupil.networking.SearchQuery
|
||||
import xyz.quaver.pupil.networking.SearchQueryPreviewParameterProvider
|
||||
import xyz.quaver.pupil.ui.theme.Blue300
|
||||
import xyz.quaver.pupil.ui.theme.Blue600
|
||||
import xyz.quaver.pupil.ui.theme.Gray300
|
||||
import xyz.quaver.pupil.ui.theme.Pink600
|
||||
import xyz.quaver.pupil.ui.theme.Red300
|
||||
import xyz.quaver.pupil.ui.theme.Yellow400
|
||||
import xyz.quaver.pupil.ui.viewmodel.MainUIState
|
||||
|
||||
private val iconMap = mapOf(
|
||||
"female" to Icons.Default.Female,
|
||||
"male" to Icons.Default.Male,
|
||||
"artist" to Icons.Default.Brush,
|
||||
"group" to Icons.Default.Group,
|
||||
"character" to Icons.Default.Face,
|
||||
"series" to Icons.Default.Book,
|
||||
"type" to Icons.Default.Folder,
|
||||
"language" to Icons.Default.Translate,
|
||||
"tag" to Icons.Default.LocalOffer
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun TagChipIcon(tag: SearchQuery.Tag) {
|
||||
val icon = iconMap[tag.namespace ?: "tag"]
|
||||
|
||||
if (icon != null)
|
||||
Icon(
|
||||
icon,
|
||||
contentDescription = "icon",
|
||||
modifier = Modifier
|
||||
.padding(4.dp)
|
||||
.size(24.dp)
|
||||
)
|
||||
else
|
||||
Spacer(Modifier.width(16.dp))
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun TagChip(
|
||||
tag: SearchQuery.Tag,
|
||||
isFavorite: Boolean = false,
|
||||
enabled: Boolean = true,
|
||||
onClick: (SearchQuery.Tag) -> Unit = { },
|
||||
leftIcon: @Composable (SearchQuery.Tag) -> Unit = { tag -> TagChipIcon(tag) },
|
||||
rightIcon: @Composable (SearchQuery.Tag) -> Unit = { _ -> Spacer(Modifier.width(16.dp)) },
|
||||
content: @Composable (SearchQuery.Tag) -> Unit = { tag -> Text(tag.tag) },
|
||||
) {
|
||||
val surfaceColor = if (isFavorite) Yellow400 else when (tag.namespace) {
|
||||
"male" -> Blue600
|
||||
"female" -> Pink600
|
||||
else -> MaterialTheme.colorScheme.surface
|
||||
}
|
||||
|
||||
val contentColor =
|
||||
if (surfaceColor == MaterialTheme.colorScheme.surface)
|
||||
MaterialTheme.colorScheme.onSurface
|
||||
else
|
||||
Color.White
|
||||
|
||||
val inner = @Composable {
|
||||
CompositionLocalProvider(
|
||||
LocalContentColor provides contentColor,
|
||||
LocalTextStyle provides MaterialTheme.typography.bodyMedium
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
leftIcon(tag)
|
||||
content(tag)
|
||||
rightIcon(tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val modifier = Modifier.height(32.dp)
|
||||
val shape = RoundedCornerShape(16.dp)
|
||||
|
||||
if (enabled)
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
shape = shape,
|
||||
color = surfaceColor,
|
||||
onClick = { onClick(tag) },
|
||||
content = inner
|
||||
)
|
||||
else
|
||||
Surface(
|
||||
modifier,
|
||||
shape = shape,
|
||||
color = surfaceColor,
|
||||
content = inner
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun QueryView(
|
||||
@PreviewParameter(SearchQueryPreviewParameterProvider::class) query: SearchQuery?,
|
||||
topLevel: Boolean = true
|
||||
) {
|
||||
val modifier = if (topLevel) {
|
||||
Modifier
|
||||
} else {
|
||||
Modifier.border(width = 0.5.dp, color = LocalContentColor.current, shape = CardDefaults.shape)
|
||||
}
|
||||
|
||||
when (query) {
|
||||
is SearchQuery.Tag -> {
|
||||
TagChip(
|
||||
query,
|
||||
enabled = false
|
||||
)
|
||||
}
|
||||
is SearchQuery.Or -> {
|
||||
Row(
|
||||
modifier = modifier.padding(vertical=2.dp, horizontal=4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
query.queries.forEachIndexed { index, subquery ->
|
||||
if (index != 0) { Text("+") }
|
||||
QueryView(subquery, topLevel = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
is SearchQuery.And -> {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
query.queries.forEach { subquery ->
|
||||
QueryView(subquery, topLevel = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
is SearchQuery.Not -> {
|
||||
Row(
|
||||
modifier = modifier.padding(vertical=2.dp, horizontal=4.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text("-")
|
||||
QueryView(query.query, topLevel = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SearchBar(
|
||||
contentType: ContentType,
|
||||
@@ -63,7 +237,7 @@ fun SearchBar(
|
||||
onTopOffsetChange: (Int) -> Unit,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
var focused by remember { mutableStateOf(false) }
|
||||
var focused by remember { mutableStateOf(true) }
|
||||
val scrimAlpha: Float by animateFloatAsState(if (focused && contentType == ContentType.SINGLE_PANE) 0.3f else 0f, label = "skrim alpha")
|
||||
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
@@ -74,10 +248,6 @@ fun SearchBar(
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(query) {
|
||||
focused = false
|
||||
}
|
||||
|
||||
BoxWithConstraints(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
@@ -102,7 +272,8 @@ fun SearchBar(
|
||||
indication = null
|
||||
) {
|
||||
focused = true
|
||||
},
|
||||
}
|
||||
.clip(RoundedCornerShape(30.dp)),
|
||||
shape = RoundedCornerShape(30.dp),
|
||||
elevation = if (focused) CardDefaults.cardElevation(
|
||||
defaultElevation = 4.dp
|
||||
@@ -119,10 +290,22 @@ fun SearchBar(
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
|
||||
)
|
||||
}
|
||||
androidx.compose.animation.AnimatedVisibility(query != null && !focused, enter = fadeIn(), exit = fadeOut()) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.heightIn(min = 60.dp)
|
||||
.horizontalScroll(rememberScrollState()),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
QueryView(query!!)
|
||||
}
|
||||
}
|
||||
androidx.compose.animation.AnimatedVisibility(focused, enter = fadeIn(), exit = fadeOut()) {
|
||||
Box(Modifier.fillMaxSize().padding(8.dp)) {
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(top = 8.dp, start = 8.dp, end = 8.dp)) {
|
||||
IconButton(
|
||||
modifier = Modifier.align(Alignment.TopStart),
|
||||
onClick = {
|
||||
focused = false
|
||||
}
|
||||
@@ -132,6 +315,10 @@ fun SearchBar(
|
||||
contentDescription = "close search bar"
|
||||
)
|
||||
}
|
||||
QueryEditor(
|
||||
query = query,
|
||||
onQueryChange = onQueryChange
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,7 +368,7 @@ fun GalleryList(
|
||||
contentType: ContentType,
|
||||
galleries: List<GalleryInfo> = emptyList(),
|
||||
openedGallery: GalleryInfo? = null,
|
||||
query: SearchQuery? = null,
|
||||
query: SearchQuery? = SearchQueryPreviewParameterProvider().values.first(),
|
||||
onQueryChange: (SearchQuery) -> Unit = {},
|
||||
onSearch: () -> Unit = { },
|
||||
selectedGalleryIds: Set<Int> = emptySet(),
|
||||
|
||||
266
app/src/main/java/xyz/quaver/pupil/ui/composable/QueryEditor.kt
Normal file
266
app/src/main/java/xyz/quaver/pupil/ui/composable/QueryEditor.kt
Normal file
@@ -0,0 +1,266 @@
|
||||
package xyz.quaver.pupil.ui.composable
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
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.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.AddCircleOutline
|
||||
import androidx.compose.material.icons.filled.RemoveCircleOutline
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardColors
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.toMutableStateList
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import xyz.quaver.pupil.R
|
||||
import xyz.quaver.pupil.networking.SearchQuery
|
||||
import xyz.quaver.pupil.ui.theme.Blue300
|
||||
import xyz.quaver.pupil.ui.theme.Gray300
|
||||
import xyz.quaver.pupil.ui.theme.Red300
|
||||
|
||||
@Composable
|
||||
fun NewQueryChip(currentQuery: SearchQuery) {
|
||||
var opened by remember { mutableStateOf(false) }
|
||||
|
||||
@Composable
|
||||
fun NewQueryRow(
|
||||
icon: ImageVector = Icons.Default.AddCircleOutline,
|
||||
text: String,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.height(32.dp)
|
||||
.clickable(onClick = onClick),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
.size(16.dp),
|
||||
imageVector = icon,
|
||||
contentDescription = text
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(end = 16.dp),
|
||||
text = text,
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Surface(shape = RoundedCornerShape(16.dp)) {
|
||||
AnimatedContent(targetState = opened, label = "add new query") { targetOpened ->
|
||||
if (targetOpened) {
|
||||
Column {
|
||||
NewQueryRow(
|
||||
icon = Icons.Default.RemoveCircleOutline,
|
||||
text = stringResource(android.R.string.cancel)
|
||||
) {
|
||||
opened = false
|
||||
}
|
||||
HorizontalDivider()
|
||||
NewQueryRow(text = stringResource(R.string.search_add_query_item_tag)) {
|
||||
|
||||
}
|
||||
if (currentQuery !is SearchQuery.And) {
|
||||
HorizontalDivider()
|
||||
NewQueryRow(text = "AND") {
|
||||
|
||||
}
|
||||
}
|
||||
if (currentQuery !is SearchQuery.Or) {
|
||||
HorizontalDivider()
|
||||
NewQueryRow(text = "OR") {
|
||||
|
||||
}
|
||||
}
|
||||
if (currentQuery !is SearchQuery.Not) {
|
||||
HorizontalDivider()
|
||||
NewQueryRow(text = "NOT") {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NewQueryRow(text = stringResource(R.string.search_add_query_item)) {
|
||||
opened = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun QueryEditorQueryView(
|
||||
query: SearchQuery?,
|
||||
onQueryAdd: (SearchQuery) -> Unit
|
||||
) {
|
||||
when (query) {
|
||||
is SearchQuery.Tag -> {
|
||||
TagChip(
|
||||
query,
|
||||
enabled = false,
|
||||
rightIcon = {
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.padding(8.dp)
|
||||
.size(16.dp),
|
||||
imageVector = Icons.Default.RemoveCircleOutline,
|
||||
contentDescription = stringResource(R.string.search_remove_query_item_description)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
is SearchQuery.Or -> {
|
||||
Card(
|
||||
colors = CardColors(
|
||||
containerColor = Blue300,
|
||||
contentColor = Color.Black,
|
||||
disabledContainerColor = Blue300,
|
||||
disabledContentColor = Color.Black
|
||||
)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
horizontalAlignment = Alignment.Start,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text("OR", modifier = Modifier.padding(horizontal = 8.dp), style = MaterialTheme.typography.labelMedium)
|
||||
Icon(
|
||||
modifier = Modifier.size(16.dp),
|
||||
imageVector = Icons.Default.RemoveCircleOutline,
|
||||
contentDescription = stringResource(xyz.quaver.pupil.R.string.search_remove_query_item_description)
|
||||
)
|
||||
}
|
||||
query.queries.forEachIndexed { index, subquery ->
|
||||
if (index != 0) { Text("+", modifier = Modifier.padding(horizontal = 8.dp)) }
|
||||
QueryEditorQueryView(subquery, onQueryAdd)
|
||||
}
|
||||
NewQueryChip(query) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is SearchQuery.And -> {
|
||||
Card(
|
||||
colors = CardColors(
|
||||
containerColor = Gray300,
|
||||
contentColor = Color.Black,
|
||||
disabledContainerColor = Gray300,
|
||||
disabledContentColor = Color.Black
|
||||
)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
horizontalAlignment = Alignment.Start,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text("AND", modifier = Modifier.padding(horizontal = 8.dp), style = MaterialTheme.typography.labelMedium)
|
||||
Icon(
|
||||
modifier = Modifier.size(16.dp),
|
||||
imageVector = Icons.Default.RemoveCircleOutline,
|
||||
contentDescription = stringResource(xyz.quaver.pupil.R.string.search_remove_query_item_description)
|
||||
)
|
||||
}
|
||||
query.queries.forEach { subquery ->
|
||||
QueryEditorQueryView(subquery, onQueryAdd)
|
||||
}
|
||||
NewQueryChip(query) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is SearchQuery.Not -> {
|
||||
Card(
|
||||
colors = CardColors(
|
||||
containerColor = Red300,
|
||||
contentColor = Color.Black,
|
||||
disabledContainerColor = Red300,
|
||||
disabledContentColor = Color.Black
|
||||
)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
horizontalAlignment = Alignment.Start,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text("-", modifier = Modifier.padding(horizontal = 8.dp), style = MaterialTheme.typography.labelMedium)
|
||||
Icon(
|
||||
modifier = Modifier.size(16.dp),
|
||||
imageVector = Icons.Default.RemoveCircleOutline,
|
||||
contentDescription = stringResource(xyz.quaver.pupil.R.string.search_remove_query_item_description)
|
||||
)
|
||||
}
|
||||
QueryEditorQueryView(query.query, onQueryAdd)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun QueryEditor(
|
||||
query: SearchQuery?,
|
||||
onQueryChange: (SearchQuery) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
if (query != null) {
|
||||
QueryEditorQueryView(query = query) {
|
||||
|
||||
}
|
||||
} else {
|
||||
NewQueryChip(null) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,3 +65,84 @@ val md_theme_dark_scrim = Color(0xFF000000)
|
||||
|
||||
|
||||
val seed = Color(0xFF4FC3F7)
|
||||
|
||||
val Gray50 = Color(0xFFF9FAFB)
|
||||
val Gray100 = Color(0xFFF3F4F6)
|
||||
val Gray200 = Color(0xFFE5E7EB)
|
||||
val Gray300 = Color(0xFFD1D5DB)
|
||||
val Gray400 = Color(0xFF9CA3AF)
|
||||
val Gray500 = Color(0xFF6B7280)
|
||||
val Gray600 = Color(0xFF4B5563)
|
||||
val Gray700 = Color(0xFF374151)
|
||||
val Gray800 = Color(0xFF1F2937)
|
||||
val Gray900 = Color(0xFF111827)
|
||||
val Red50 = Color(0xFFFEF2F2)
|
||||
val Red100 = Color(0xFFFEE2E2)
|
||||
val Red200 = Color(0xFFFECACA)
|
||||
val Red300 = Color(0xFFFCA5A5)
|
||||
val Red400 = Color(0xFFF87171)
|
||||
val Red500 = Color(0xFFEF4444)
|
||||
val Red600 = Color(0xFFDC2626)
|
||||
val Red700 = Color(0xFFB91C1C)
|
||||
val Red800 = Color(0xFF991B1B)
|
||||
val Red900 = Color(0xFF7F1D1D)
|
||||
val Yellow50 = Color(0xFFFFFBEB)
|
||||
val Yellow100 = Color(0xFFFEF3C7)
|
||||
val Yellow200 = Color(0xFFFDE68A)
|
||||
val Yellow300 = Color(0xFFFCD34D)
|
||||
val Yellow400 = Color(0xFFFBBF24)
|
||||
val Yellow500 = Color(0xFFF59E0B)
|
||||
val Yellow600 = Color(0xFFD97706)
|
||||
val Yellow700 = Color(0xFFB45309)
|
||||
val Yellow800 = Color(0xFF92400E)
|
||||
val Yellow900 = Color(0xFF78350F)
|
||||
val Green50 = Color(0xFFECFDF5)
|
||||
val Green100 = Color(0xFFD1FAE5)
|
||||
val Green200 = Color(0xFFA7F3D0)
|
||||
val Green300 = Color(0xFF6EE7B7)
|
||||
val Green400 = Color(0xFF34D399)
|
||||
val Green500 = Color(0xFF10B981)
|
||||
val Green600 = Color(0xFF059669)
|
||||
val Green700 = Color(0xFF047857)
|
||||
val Green800 = Color(0xFF065F46)
|
||||
val Green900 = Color(0xFF064E3B)
|
||||
val Blue50 = Color(0xFFEFF6FF)
|
||||
val Blue100 = Color(0xFFDBEAFE)
|
||||
val Blue200 = Color(0xFFBFDBFE)
|
||||
val Blue300 = Color(0xFF93C5FD)
|
||||
val Blue400 = Color(0xFF60A5FA)
|
||||
val Blue500 = Color(0xFF3B82F6)
|
||||
val Blue600 = Color(0xFF2563EB)
|
||||
val Blue700 = Color(0xFF1D4ED8)
|
||||
val Blue800 = Color(0xFF1E40AF)
|
||||
val Blue900 = Color(0xFF1E3A8A)
|
||||
val Indigo50 = Color(0xFFEEF2FF)
|
||||
val Indigo100 = Color(0xFFE0E7FF)
|
||||
val Indigo200 = Color(0xFFC7D2FE)
|
||||
val Indigo300 = Color(0xFFA5B4FC)
|
||||
val Indigo400 = Color(0xFF818CF8)
|
||||
val Indigo500 = Color(0xFF6366F1)
|
||||
val Indigo600 = Color(0xFF4F46E5)
|
||||
val Indigo700 = Color(0xFF4338CA)
|
||||
val Indigo800 = Color(0xFF3730A3)
|
||||
val Indigo900 = Color(0xFF312E81)
|
||||
val Purple50 = Color(0xFFF5F3FF)
|
||||
val Purple100 = Color(0xFFEDE9FE)
|
||||
val Purple200 = Color(0xFFDDD6FE)
|
||||
val Purple300 = Color(0xFFC4B5FD)
|
||||
val Purple400 = Color(0xFFA78BFA)
|
||||
val Purple500 = Color(0xFF8B5CF6)
|
||||
val Purple600 = Color(0xFF7C3AED)
|
||||
val Purple700 = Color(0xFF6D28D9)
|
||||
val Purple800 = Color(0xFF5B21B6)
|
||||
val Purple900 = Color(0xFF4C1D95)
|
||||
val Pink50 = Color(0xFFFDF2F8)
|
||||
val Pink100 = Color(0xFFFCE7F3)
|
||||
val Pink200 = Color(0xFFFBCFE8)
|
||||
val Pink300 = Color(0xFFF9A8D4)
|
||||
val Pink400 = Color(0xFFF472B6)
|
||||
val Pink500 = Color(0xFFEC4899)
|
||||
val Pink600 = Color(0xFFDB2777)
|
||||
val Pink700 = Color(0xFFBE185D)
|
||||
val Pink800 = Color(0xFF9D174D)
|
||||
val Pink900 = Color(0xFF831843)
|
||||
@@ -79,6 +79,7 @@
|
||||
<string name="lock_corrupted">ロックファイルが破損されています。Pupilを再再インストールしてください。</string>
|
||||
<string name="settings_dark_mode_title">ダークモード</string>
|
||||
<string name="settings_dark_mode_summary">夜にシコりたい方々へ</string>
|
||||
<string name="search_add_query_item">追加</string>
|
||||
<string name="gallery_details">ギャラリー情報</string>
|
||||
<string name="gallery_artists">アーティスト</string>
|
||||
<string name="gallery_characters">キャラクター</string>
|
||||
@@ -161,4 +162,6 @@
|
||||
<string name="settings_networking">ネットワーク</string>
|
||||
<string name="settings_recover_downloads">ダウンロードデータベースを再構築</string>
|
||||
<string name="main_close_navigation_drawer">メニューを閉じる</string>
|
||||
<string name="search_remove_query_item_description">検索構文を除去</string>
|
||||
<string name="search_add_query_item_tag">タグ</string>
|
||||
</resources>
|
||||
@@ -77,6 +77,7 @@
|
||||
<string name="lock_corrupted">잠금 파일이 손상되었습니다! 앱을 재설치 해 주시기 바랍니다.</string>
|
||||
<string name="settings_dark_mode_title">다크 모드</string>
|
||||
<string name="settings_dark_mode_summary">딥 다크한 모오드</string>
|
||||
<string name="search_add_query_item">추가</string>
|
||||
<string name="gallery_details">갤러리 정보</string>
|
||||
<string name="gallery_artists">작가</string>
|
||||
<string name="gallery_characters">캐릭터</string>
|
||||
@@ -161,4 +162,6 @@
|
||||
<string name="settings_networking">네트워크</string>
|
||||
<string name="settings_recover_downloads">다운로드 데이터베이스 복구</string>
|
||||
<string name="main_close_navigation_drawer">메뉴 닫기</string>
|
||||
<string name="search_remove_query_item_description">검색 구문 제거</string>
|
||||
<string name="search_add_query_item_tag">태그</string>
|
||||
</resources>
|
||||
@@ -66,8 +66,6 @@
|
||||
<string name="main_drawer_group_contact_email">Email me!</string>
|
||||
<string name="main_drawer_grouop_contact_discord">Discord</string>
|
||||
|
||||
<string name="main_menu_thin">Thin Mode</string>
|
||||
|
||||
<string name="main_menu_sort">Sort</string>
|
||||
<string name="main_menu_sort_newest">Newest</string>
|
||||
<string name="main_menu_sort_popular">Popular</string>
|
||||
@@ -95,6 +93,10 @@
|
||||
<string name="search_show_histories">Show histories</string>
|
||||
<string name="search_show_tags">Show favorite tags</string>
|
||||
|
||||
<string name="search_add_query_item">Add</string>
|
||||
<string name="search_add_query_item_tag">Tag</string>
|
||||
<string name="search_remove_query_item_description">Remove query item</string>
|
||||
|
||||
<string name="gallery_details">Details</string>
|
||||
<string name="gallery_thumbnails">Thumbnails</string>
|
||||
<string name="gallery_related">Related Galleries</string>
|
||||
@@ -253,5 +255,6 @@
|
||||
<string name="import_old_galleries_notification_text" translatable="false">%1$d/%2$d</string>
|
||||
<string name="import_old_galleries_notification_done">Importing completed</string>
|
||||
<string name="settings_lock_fingerprint_prompt_subtitle">Ah Shit, Here we go again</string>
|
||||
<string name="main_menu_thin">Thin Mode</string>
|
||||
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user