Update Compose Material Dialogs and use their list options

This commit is contained in:
Syer10
2022-05-17 17:12:26 -04:00
parent 0b8adb6c40
commit 17dfdcfb73
8 changed files with 65 additions and 159 deletions

View File

@@ -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"

View File

@@ -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)

View File

@@ -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()

View File

@@ -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)

View File

@@ -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()

View File

@@ -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)

View File

@@ -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()

View File

@@ -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,