mirror of
https://github.com/Suwayomi/TachideskJUI.git
synced 2026-01-20 18:52:33 +01:00
Update Compose Material Dialogs and use their list options
This commit is contained in:
@@ -11,7 +11,7 @@ composeGradle = "1.1.1"
|
||||
voyager = "1.0.0-beta16"
|
||||
accompanist = "0.24.4"
|
||||
kamel = "0.3.0"
|
||||
materialDialogs = "0.7.0"
|
||||
materialDialogs = "0.7.1"
|
||||
|
||||
# Android
|
||||
androidGradle = "7.0.4"
|
||||
|
||||
@@ -29,25 +29,18 @@ import androidx.compose.foundation.layout.BoxScope
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.defaultMinSize
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.requiredHeight
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.Checkbox
|
||||
import androidx.compose.material.ContentAlpha
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.LocalContentColor
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.RadioButton
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Switch
|
||||
import androidx.compose.material.Text
|
||||
@@ -60,7 +53,6 @@ import androidx.compose.runtime.getValue
|
||||
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.draw.clip
|
||||
@@ -84,6 +76,8 @@ import com.vanpra.composematerialdialogs.MaterialDialogButtons
|
||||
import com.vanpra.composematerialdialogs.MaterialDialogState
|
||||
import com.vanpra.composematerialdialogs.TextFieldStyle
|
||||
import com.vanpra.composematerialdialogs.input
|
||||
import com.vanpra.composematerialdialogs.listItemsMultiChoice
|
||||
import com.vanpra.composematerialdialogs.listItemsSingleChoice
|
||||
import com.vanpra.composematerialdialogs.rememberMaterialDialogState
|
||||
import com.vanpra.composematerialdialogs.title
|
||||
|
||||
@@ -274,32 +268,16 @@ fun <T> ChoiceDialog(
|
||||
title(title)
|
||||
Box {
|
||||
val listState = rememberLazyListState()
|
||||
LazyColumn(Modifier.defaultMinSize(minHeight = 64.dp).fillMaxWidth(), listState) {
|
||||
items(items) { (value, text) ->
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.requiredHeight(48.dp)
|
||||
.fillMaxWidth()
|
||||
.clickable(
|
||||
onClick = {
|
||||
onSelected(value)
|
||||
state.hide()
|
||||
}
|
||||
)
|
||||
.padding(horizontal = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
RadioButton(
|
||||
selected = value == selected,
|
||||
onClick = {
|
||||
onSelected(value)
|
||||
state.hide()
|
||||
},
|
||||
)
|
||||
Text(text = text, modifier = Modifier.padding(start = 24.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
listItemsSingleChoice(
|
||||
items.map { it.second },
|
||||
state = listState,
|
||||
initialSelection = items.indexOfFirst { it.first == selected }.takeUnless { it == -1 },
|
||||
waitForPositiveButton = false,
|
||||
onChoiceChange = {
|
||||
onSelected(items[it].first)
|
||||
submit()
|
||||
}
|
||||
)
|
||||
VerticalScrollbar(
|
||||
rememberScrollbarAdapter(listState),
|
||||
Modifier.align(Alignment.CenterEnd)
|
||||
@@ -319,13 +297,10 @@ fun <T> MultiSelectDialog(
|
||||
onFinished: (List<T>) -> Unit,
|
||||
title: String,
|
||||
) {
|
||||
val checked = remember(selected) { selected.orEmpty().toMutableStateList() }
|
||||
MaterialDialog(
|
||||
state,
|
||||
buttons = {
|
||||
positiveButton(stringResource(MR.strings.action_ok)) {
|
||||
onFinished(checked)
|
||||
}
|
||||
positiveButton(stringResource(MR.strings.action_ok))
|
||||
negativeButton(stringResource(MR.strings.action_cancel))
|
||||
},
|
||||
properties = getMaterialDialogProperties(),
|
||||
@@ -335,35 +310,20 @@ fun <T> MultiSelectDialog(
|
||||
}
|
||||
) {
|
||||
title(title)
|
||||
val listState = rememberLazyListState()
|
||||
Box {
|
||||
LazyColumn(Modifier.defaultMinSize(minHeight = 64.dp).fillMaxWidth(), listState) {
|
||||
items(items) { (value, text) ->
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.requiredHeight(48.dp)
|
||||
.fillMaxWidth()
|
||||
.clickable(
|
||||
onClick = {
|
||||
if (value in checked) {
|
||||
checked -= value
|
||||
} else {
|
||||
checked += value
|
||||
}
|
||||
}
|
||||
)
|
||||
.padding(horizontal = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Checkbox(
|
||||
checked = value in checked,
|
||||
onCheckedChange = null,
|
||||
)
|
||||
Text(text = text, modifier = Modifier.padding(start = 24.dp))
|
||||
}
|
||||
}
|
||||
item { Spacer(Modifier.height(80.dp)) }
|
||||
}
|
||||
val listState = rememberLazyListState()
|
||||
listItemsMultiChoice(
|
||||
items.map { it.second },
|
||||
state = listState,
|
||||
initialSelection = selected?.mapNotNull { item ->
|
||||
items.indexOfFirst { it.first == item }.takeUnless { it == -1 }
|
||||
}
|
||||
?.toSet()
|
||||
.orEmpty(),
|
||||
onCheckedChange = { indexes ->
|
||||
onFinished(indexes.map { items[it].first })
|
||||
}
|
||||
)
|
||||
VerticalScrollbar(
|
||||
rememberScrollbarAdapter(listState),
|
||||
Modifier.align(Alignment.CenterEnd)
|
||||
|
||||
@@ -49,8 +49,8 @@ class ExtensionsScreenViewModel @Inject constructor(
|
||||
}.stateIn(scope, SharingStarted.Eagerly, emptyMap())
|
||||
|
||||
val availableLangs = extensionList.filterNotNull().map { langs ->
|
||||
langs.map { it.lang }.toSet()
|
||||
}.stateIn(scope, SharingStarted.Eagerly, emptySet())
|
||||
langs.map { it.lang }.distinct()
|
||||
}.stateIn(scope, SharingStarted.Eagerly, emptyList())
|
||||
|
||||
private val _isLoading = MutableStateFlow(true)
|
||||
val isLoading = _isLoading.asStateFlow()
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
package ca.gosyer.jui.ui.extensions.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@@ -27,16 +25,12 @@ import androidx.compose.material.Button
|
||||
import androidx.compose.material.ContentAlpha
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Switch
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.Translate
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.toMutableStateList
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@@ -64,6 +58,7 @@ import ca.gosyer.jui.uicore.image.KamelImage
|
||||
import ca.gosyer.jui.uicore.resources.stringResource
|
||||
import com.vanpra.composematerialdialogs.MaterialDialog
|
||||
import com.vanpra.composematerialdialogs.MaterialDialogState
|
||||
import com.vanpra.composematerialdialogs.listItemsMultiChoice
|
||||
import com.vanpra.composematerialdialogs.rememberMaterialDialogState
|
||||
import com.vanpra.composematerialdialogs.title
|
||||
import io.kamel.image.lazyPainterResource
|
||||
@@ -75,7 +70,7 @@ fun ExtensionsScreenContent(
|
||||
query: String?,
|
||||
setQuery: (String) -> Unit,
|
||||
enabledLangs: Set<String>,
|
||||
availableLangs: Set<String>,
|
||||
availableLangs: List<String>,
|
||||
setEnabledLanguages: (Set<String>) -> Unit,
|
||||
installExtension: (Extension) -> Unit,
|
||||
updateExtension: (Extension) -> Unit,
|
||||
@@ -205,51 +200,34 @@ fun ExtensionItem(
|
||||
fun LanguageDialog(
|
||||
state: MaterialDialogState,
|
||||
enabledLangs: Set<String>,
|
||||
availableLangs: Set<String>,
|
||||
availableLangs: List<String>,
|
||||
setLangs: (Set<String>) -> Unit
|
||||
) {
|
||||
val modifiedLangs = remember(enabledLangs) { enabledLangs.toMutableStateList() }
|
||||
MaterialDialog(
|
||||
state,
|
||||
buttons = {
|
||||
positiveButton(stringResource(MR.strings.action_ok)) {
|
||||
setLangs(modifiedLangs.toSet())
|
||||
}
|
||||
positiveButton(stringResource(MR.strings.action_ok))
|
||||
negativeButton(stringResource(MR.strings.action_cancel))
|
||||
},
|
||||
properties = getMaterialDialogProperties(),
|
||||
) {
|
||||
title(BuildKonfig.NAME)
|
||||
|
||||
Box {
|
||||
val locale = remember { Locale.current }
|
||||
val listState = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxWidth(), listState) {
|
||||
items(availableLangs.toList()) { lang ->
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.height(48.dp)
|
||||
.clickable {
|
||||
if (lang in modifiedLangs) {
|
||||
modifiedLangs -= lang
|
||||
} else {
|
||||
modifiedLangs += lang
|
||||
}
|
||||
}
|
||||
.padding(horizontal = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
val langName by derivedStateOf {
|
||||
Locale(lang).getDisplayName(locale).ifBlank { lang.capitalize(Locale.current) }
|
||||
}
|
||||
Text(langName)
|
||||
Switch(
|
||||
checked = lang in modifiedLangs,
|
||||
onCheckedChange = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
listItemsMultiChoice(
|
||||
list = availableLangs.map { lang ->
|
||||
Locale(lang).getDisplayName(locale).ifBlank { lang.capitalize(Locale.current) }
|
||||
},
|
||||
state = listState,
|
||||
initialSelection = enabledLangs.mapNotNull { lang ->
|
||||
availableLangs.indexOfFirst { it == lang }.takeUnless { it == -1 }
|
||||
}.toSet(),
|
||||
onCheckedChange = { indexes ->
|
||||
setLangs(indexes.map { availableLangs[it] }.toSet())
|
||||
}
|
||||
)
|
||||
VerticalScrollbar(
|
||||
rememberScrollbarAdapter(listState),
|
||||
Modifier.align(Alignment.CenterEnd)
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
package ca.gosyer.jui.ui.manga.components
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -17,23 +15,17 @@ import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.defaultMinSize
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
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.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.Checkbox
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.toMutableStateList
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.FilterQuality
|
||||
@@ -54,6 +46,7 @@ import ca.gosyer.jui.uicore.resources.stringResource
|
||||
import com.google.accompanist.flowlayout.FlowRow
|
||||
import com.vanpra.composematerialdialogs.MaterialDialog
|
||||
import com.vanpra.composematerialdialogs.MaterialDialogState
|
||||
import com.vanpra.composematerialdialogs.listItemsMultiChoice
|
||||
import com.vanpra.composematerialdialogs.title
|
||||
import io.kamel.image.lazyPainterResource
|
||||
|
||||
@@ -171,44 +164,28 @@ fun CategorySelectDialog(
|
||||
oldCategories: List<Category>,
|
||||
onPositiveClick: (List<Category>, List<Category>) -> Unit
|
||||
) {
|
||||
val enabledCategories = remember(oldCategories) { oldCategories.toMutableStateList() }
|
||||
MaterialDialog(
|
||||
state,
|
||||
buttons = {
|
||||
positiveButton(stringResource(MR.strings.action_ok)) {
|
||||
onPositiveClick(enabledCategories.toList(), oldCategories)
|
||||
}
|
||||
positiveButton(stringResource(MR.strings.action_ok))
|
||||
negativeButton(stringResource(MR.strings.action_cancel))
|
||||
},
|
||||
properties = getMaterialDialogProperties(),
|
||||
) {
|
||||
title(stringResource(MR.strings.select_categories))
|
||||
val listState = rememberLazyListState()
|
||||
|
||||
Box {
|
||||
LazyColumn(state = listState) {
|
||||
items(categories) { category ->
|
||||
Row(
|
||||
Modifier.fillMaxWidth()
|
||||
.height(48.dp)
|
||||
.clickable {
|
||||
if (category in enabledCategories) {
|
||||
enabledCategories -= category
|
||||
} else {
|
||||
enabledCategories += category
|
||||
}
|
||||
}
|
||||
.padding(horizontal = 16.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(category.name, style = MaterialTheme.typography.subtitle1)
|
||||
Checkbox(
|
||||
category in enabledCategories,
|
||||
onCheckedChange = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
val listState = rememberLazyListState()
|
||||
listItemsMultiChoice(
|
||||
list = categories.map { it.name },
|
||||
state = listState,
|
||||
initialSelection = oldCategories.mapNotNull { category ->
|
||||
categories.indexOfFirst { it.id == category.id }.takeUnless { it == -1 }
|
||||
}.toSet(),
|
||||
onCheckedChange = { indexes ->
|
||||
onPositiveClick(indexes.map { categories[it] }, oldCategories)
|
||||
}
|
||||
)
|
||||
VerticalScrollbar(
|
||||
modifier = Modifier.align(Alignment.CenterEnd)
|
||||
.fillMaxHeight()
|
||||
|
||||
@@ -12,13 +12,10 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.CircularProgressIndicator
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.Check
|
||||
import androidx.compose.material.icons.rounded.Warning
|
||||
@@ -58,6 +55,7 @@ import cafe.adriel.voyager.core.screen.ScreenKey
|
||||
import cafe.adriel.voyager.core.screen.uniqueScreenKey
|
||||
import com.vanpra.composematerialdialogs.MaterialDialog
|
||||
import com.vanpra.composematerialdialogs.MaterialDialogState
|
||||
import com.vanpra.composematerialdialogs.listItems
|
||||
import com.vanpra.composematerialdialogs.rememberMaterialDialogState
|
||||
import com.vanpra.composematerialdialogs.title
|
||||
import io.ktor.client.plugins.onDownload
|
||||
@@ -365,14 +363,7 @@ private fun MissingSourcesDialog(
|
||||
title(stringResource(MR.strings.missing_sources))
|
||||
Box {
|
||||
val listState = rememberLazyListState()
|
||||
LazyColumn(Modifier.fillMaxSize(), state = listState) {
|
||||
item {
|
||||
Text(stringResource(MR.strings.missing_sources), style = MaterialTheme.typography.subtitle2)
|
||||
}
|
||||
items(missingSources) {
|
||||
Text(it)
|
||||
}
|
||||
}
|
||||
listItems(missingSources, state = listState)
|
||||
VerticalScrollbar(
|
||||
rememberScrollbarAdapter(listState),
|
||||
Modifier.align(Alignment.CenterEnd)
|
||||
|
||||
@@ -43,8 +43,8 @@ class SourceHomeScreenViewModel @Inject constructor(
|
||||
}.stateIn(scope, SharingStarted.Eagerly, emptyList())
|
||||
|
||||
val sourceLanguages = installedSources.map { sources ->
|
||||
sources.map { it.lang }.toSet() - Source.LOCAL_SOURCE_LANG
|
||||
}.stateIn(scope, SharingStarted.Eagerly, emptySet())
|
||||
sources.map { it.lang }.distinct() - Source.LOCAL_SOURCE_LANG
|
||||
}.stateIn(scope, SharingStarted.Eagerly, emptyList())
|
||||
|
||||
private val _query = MutableStateFlow("")
|
||||
val query = _query.asStateFlow()
|
||||
|
||||
@@ -66,7 +66,7 @@ fun SourceHomeScreenContent(
|
||||
isLoading: Boolean,
|
||||
sources: List<Source>,
|
||||
languages: Set<String>,
|
||||
sourceLanguages: Set<String>,
|
||||
sourceLanguages: List<String>,
|
||||
setEnabledLanguages: (Set<String>) -> Unit,
|
||||
query: String,
|
||||
setQuery: (String) -> Unit,
|
||||
|
||||
Reference in New Issue
Block a user