mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-19 08:45:27 +02:00
Refactored units list composables
This commit is contained in:
parent
bc55e23e04
commit
2bfacd9e42
@ -1,5 +1,6 @@
|
|||||||
package com.sadellie.unitto.data.units
|
package com.sadellie.unitto.data.units
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes
|
||||||
import com.sadellie.unitto.R
|
import com.sadellie.unitto.R
|
||||||
|
|
||||||
val ALL_UNIT_GROUPS: List<UnitGroup> by lazy {
|
val ALL_UNIT_GROUPS: List<UnitGroup> by lazy {
|
||||||
@ -10,7 +11,10 @@ val ALL_UNIT_GROUPS: List<UnitGroup> by lazy {
|
|||||||
* As not all measurements can be converted between into other, we separate them into groups.
|
* As not all measurements can be converted between into other, we separate them into groups.
|
||||||
* Within one groups all measurements can be converted
|
* Within one groups all measurements can be converted
|
||||||
*/
|
*/
|
||||||
enum class UnitGroup(val res: Int, val canNegate: Boolean = false) {
|
enum class UnitGroup(
|
||||||
|
@StringRes val res: Int,
|
||||||
|
val canNegate: Boolean = false
|
||||||
|
) {
|
||||||
LENGTH(res = R.string.length),
|
LENGTH(res = R.string.length),
|
||||||
CURRENCY(res = R.string.currency),
|
CURRENCY(res = R.string.currency),
|
||||||
MASS(res = R.string.mass),
|
MASS(res = R.string.mass),
|
||||||
|
@ -84,17 +84,17 @@ fun SecondScreen(
|
|||||||
)
|
)
|
||||||
UnitsList(
|
UnitsList(
|
||||||
groupedUnits = unitsList,
|
groupedUnits = unitsList,
|
||||||
changeAction = { viewModel.changeUnitFrom(it); focusManager.clearFocus(true); navigateUp() },
|
selectAction = { viewModel.changeUnitFrom(it); focusManager.clearFocus(true); navigateUp() },
|
||||||
favoriteAction = { viewModel.favoriteUnit(it) },
|
favoriteAction = { viewModel.favoriteUnit(it) },
|
||||||
currentUnit = viewModel.unitFrom,
|
currentUnit = viewModel.unitFrom,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
UnitsList(
|
UnitsList(
|
||||||
groupedUnits = unitsList,
|
groupedUnits = unitsList,
|
||||||
changeAction = { viewModel.changeUnitTo(it); focusManager.clearFocus(true); navigateUp() },
|
selectAction = { viewModel.changeUnitTo(it); focusManager.clearFocus(true); navigateUp() },
|
||||||
favoriteAction = { viewModel.favoriteUnit(it) },
|
favoriteAction = { viewModel.favoriteUnit(it) },
|
||||||
currentUnit = viewModel.unitTo,
|
currentUnit = viewModel.unitTo,
|
||||||
inputValue = viewModel.mainUIState.inputValue.toBigDecimal(),
|
input = viewModel.mainUIState.inputValue.toBigDecimal(),
|
||||||
unitFrom = viewModel.unitFrom
|
unitFrom = viewModel.unitFrom
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ import androidx.compose.material3.IconButton
|
|||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@ -40,34 +39,29 @@ import com.sadellie.unitto.R
|
|||||||
import com.sadellie.unitto.data.units.AbstractUnit
|
import com.sadellie.unitto.data.units.AbstractUnit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents one list item. Once clicked will navigate up
|
* Represents one list item. Once clicked will navigate up.
|
||||||
*
|
*
|
||||||
* @param modifier Modifier that will be applied to a box that surrounds row.
|
* @param unit The unit itself.
|
||||||
* @param changeAction Function to change current unit. Called when choosing unit
|
* @param isSelected Whether this unit is selected or not (current pair of unit).
|
||||||
* @param favoriteAction Function to mark unit as favorite. It's a toggle
|
* @param selectAction Function to change current unit. Called when choosing unit.
|
||||||
* @param item The unit itself
|
* @param favoriteAction Function to mark unit as favorite. It's a toggle.
|
||||||
* @param isSelected Whether this unit is selected or not (current pair of unit)
|
* @param shortNameLabel String on the second line.
|
||||||
* @param convertValue Used for right side units. Shows conversion from unit on the left
|
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun UnitListItem(
|
private fun BasicUnitListItem(
|
||||||
modifier: Modifier,
|
unit: AbstractUnit,
|
||||||
changeAction: (AbstractUnit) -> Unit,
|
|
||||||
favoriteAction: (AbstractUnit) -> Unit,
|
|
||||||
item: AbstractUnit,
|
|
||||||
isSelected: Boolean,
|
isSelected: Boolean,
|
||||||
convertValue: (AbstractUnit) -> String
|
selectAction: (AbstractUnit) -> Unit,
|
||||||
|
favoriteAction: (AbstractUnit) -> Unit,
|
||||||
|
shortNameLabel: String
|
||||||
) {
|
) {
|
||||||
var isFavorite: Boolean by rememberSaveable { mutableStateOf(item.isFavorite) }
|
var isFavorite: Boolean by rememberSaveable { mutableStateOf(unit.isFavorite) }
|
||||||
var convertedValue: String by remember { mutableStateOf("") }
|
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = Modifier
|
||||||
.clickable(
|
.clickable(
|
||||||
interactionSource = remember { MutableInteractionSource() },
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
indication = rememberRipple(), // You can also change the color and radius of the ripple
|
indication = rememberRipple(), // You can also change the color and radius of the ripple
|
||||||
onClick = {
|
onClick = { selectAction(unit) }
|
||||||
changeAction(item)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
.padding(horizontal = 12.dp)
|
.padding(horizontal = 12.dp)
|
||||||
) {
|
) {
|
||||||
@ -87,19 +81,19 @@ fun UnitListItem(
|
|||||||
.weight(1f)
|
.weight(1f)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(id = item.displayName),
|
text = stringResource(id = unit.displayName),
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis
|
overflow = TextOverflow.Ellipsis
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text = convertedValue + stringResource(id = item.shortName),
|
text = shortNameLabel,
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis
|
overflow = TextOverflow.Ellipsis
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
IconButton(onClick = { favoriteAction(item); isFavorite = !isFavorite }) {
|
IconButton(onClick = { favoriteAction(unit); isFavorite = !isFavorite }) {
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
targetState = isFavorite,
|
targetState = isFavorite,
|
||||||
transitionSpec = {
|
transitionSpec = {
|
||||||
@ -107,15 +101,57 @@ fun UnitListItem(
|
|||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
if (item.isFavorite) Icons.Filled.Favorite else Icons.Filled.FavoriteBorder,
|
if (unit.isFavorite) Icons.Filled.Favorite else Icons.Filled.FavoriteBorder,
|
||||||
contentDescription = stringResource(id = R.string.favorite_button_description)
|
contentDescription = stringResource(id = R.string.favorite_button_description)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
// Converting value
|
|
||||||
convertedValue = convertValue(item)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents one list item. Once clicked will navigate up. Has without conversion.
|
||||||
|
*
|
||||||
|
* @param unit The unit itself.
|
||||||
|
* @param isSelected Whether this unit is selected or not (current pair of unit).
|
||||||
|
* @param selectAction Function to change current unit. Called when choosing unit.
|
||||||
|
* @param favoriteAction Function to mark unit as favorite. It's a toggle.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun UnitListItem(
|
||||||
|
unit: AbstractUnit,
|
||||||
|
isSelected: Boolean,
|
||||||
|
selectAction: (AbstractUnit) -> Unit,
|
||||||
|
favoriteAction: (AbstractUnit) -> Unit,
|
||||||
|
) = BasicUnitListItem(
|
||||||
|
unit = unit,
|
||||||
|
isSelected = isSelected,
|
||||||
|
selectAction = selectAction,
|
||||||
|
favoriteAction = favoriteAction,
|
||||||
|
stringResource(id = unit.shortName)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents one list item. Once clicked will navigate up. Has with conversion.
|
||||||
|
*
|
||||||
|
* @param unit The unit itself.
|
||||||
|
* @param isSelected Whether this unit is selected or not (current pair of unit).
|
||||||
|
* @param selectAction Function to change current unit. Called when choosing unit.
|
||||||
|
* @param favoriteAction Function to mark unit as favorite. It's a toggle.
|
||||||
|
* @param convertValue Function to call that will convert this unit.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun UnitListItem(
|
||||||
|
unit: AbstractUnit,
|
||||||
|
isSelected: Boolean,
|
||||||
|
selectAction: (AbstractUnit) -> Unit,
|
||||||
|
favoriteAction: (AbstractUnit) -> Unit,
|
||||||
|
convertValue: (AbstractUnit) -> String
|
||||||
|
) = BasicUnitListItem(
|
||||||
|
unit = unit,
|
||||||
|
isSelected = isSelected,
|
||||||
|
selectAction = selectAction,
|
||||||
|
favoriteAction = favoriteAction,
|
||||||
|
shortNameLabel = "${convertValue(unit)} ${stringResource(id = unit.shortName)}"
|
||||||
|
)
|
@ -19,22 +19,18 @@ import java.math.BigDecimal
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component with grouped units
|
* Component with grouped units.
|
||||||
*
|
*
|
||||||
* @param groupedUnits Grouped [AbstractUnit]s to be listed
|
* @param groupedUnits Grouped [AbstractUnit]s to be listed.
|
||||||
* @param changeAction Action to perform when clicking on a list item
|
* @param selectAction Action to perform when clicking on a list item.
|
||||||
* @param favoriteAction Action to perform when clicking "favorite" button on list item
|
* @param favoriteAction Action to perform when clicking "favorite" button on list item.
|
||||||
* @param inputValue Current input value. Used for right side screen
|
* @param currentUnit Currently selected unit. Will be visually distinguishable.
|
||||||
* @param unitFrom Current unit on the left. Used for right side screen
|
|
||||||
* @param currentUnit Currently selected unit. Will be visually distinguishable
|
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun UnitsList(
|
fun UnitsList(
|
||||||
groupedUnits: Map<UnitGroup, List<AbstractUnit>>,
|
groupedUnits: Map<UnitGroup, List<AbstractUnit>>,
|
||||||
changeAction: (AbstractUnit) -> Unit,
|
selectAction: (AbstractUnit) -> Unit,
|
||||||
favoriteAction: (AbstractUnit) -> Unit,
|
favoriteAction: (AbstractUnit) -> Unit,
|
||||||
inputValue: BigDecimal = BigDecimal.ONE,
|
|
||||||
unitFrom: AbstractUnit? = null,
|
|
||||||
currentUnit: AbstractUnit,
|
currentUnit: AbstractUnit,
|
||||||
) {
|
) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
@ -42,41 +38,82 @@ fun UnitsList(
|
|||||||
content = {
|
content = {
|
||||||
if (groupedUnits.isEmpty()) {
|
if (groupedUnits.isEmpty()) {
|
||||||
item { SearchPlaceholder() }
|
item { SearchPlaceholder() }
|
||||||
} else {
|
return@LazyColumn
|
||||||
groupedUnits.forEach { (unitGroup, listOfUnits) ->
|
|
||||||
stickyHeader {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier
|
|
||||||
.background(MaterialTheme.colorScheme.background)
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(vertical = 12.dp, horizontal = 8.dp),
|
|
||||||
text = stringResource(id = unitGroup.res),
|
|
||||||
style = MaterialTheme.typography.titleMedium,
|
|
||||||
color = MaterialTheme.colorScheme.primary
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
groupedUnits.forEach { (unitGroup, listOfUnits) ->
|
||||||
|
stickyHeader { Header(text = stringResource(id = unitGroup.res)) }
|
||||||
items(items = listOfUnits, key = { it.unitId }) { unit ->
|
items(items = listOfUnits, key = { it.unitId }) { unit ->
|
||||||
UnitListItem(
|
UnitListItem(
|
||||||
modifier = Modifier,
|
unit = unit,
|
||||||
changeAction = changeAction,
|
|
||||||
favoriteAction = favoriteAction,
|
|
||||||
item = unit,
|
|
||||||
isSelected = currentUnit == unit,
|
isSelected = currentUnit == unit,
|
||||||
convertValue = {
|
selectAction = selectAction,
|
||||||
if (unitFrom != null) {
|
favoriteAction = favoriteAction
|
||||||
Formatter.format(
|
|
||||||
unitFrom
|
|
||||||
.convert(it, inputValue, 3)
|
|
||||||
.toPlainString()
|
|
||||||
).plus(" ")
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component with grouped units/
|
||||||
|
*
|
||||||
|
* @param groupedUnits Grouped [AbstractUnit]s to be listed.
|
||||||
|
* @param selectAction Action to perform when clicking on a list item.
|
||||||
|
* @param favoriteAction Action to perform when clicking "favorite" button on list item.
|
||||||
|
* @param currentUnit Currently selected unit. Will be visually distinguishable.
|
||||||
|
* @param unitFrom Unit to convert from. Used for conversion in short name field.
|
||||||
|
* @param input Current input value. Used for conversion in short name field.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun UnitsList(
|
||||||
|
groupedUnits: Map<UnitGroup, List<AbstractUnit>>,
|
||||||
|
selectAction: (AbstractUnit) -> Unit,
|
||||||
|
favoriteAction: (AbstractUnit) -> Unit,
|
||||||
|
currentUnit: AbstractUnit,
|
||||||
|
unitFrom: AbstractUnit,
|
||||||
|
input: BigDecimal
|
||||||
|
) {
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
content = {
|
||||||
|
if (groupedUnits.isEmpty()) {
|
||||||
|
item { SearchPlaceholder() }
|
||||||
|
return@LazyColumn
|
||||||
|
}
|
||||||
|
groupedUnits.forEach { (unitGroup, listOfUnits) ->
|
||||||
|
stickyHeader { Header(text = stringResource(id = unitGroup.res)) }
|
||||||
|
items(items = listOfUnits, key = { it.unitId }) { unit ->
|
||||||
|
UnitListItem(
|
||||||
|
unit = unit,
|
||||||
|
isSelected = currentUnit == unit,
|
||||||
|
selectAction = selectAction,
|
||||||
|
favoriteAction = favoriteAction,
|
||||||
|
convertValue = {
|
||||||
|
Formatter.format(unitFrom.convert(unit, input, 3).toPlainString())
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit group header.
|
||||||
|
*
|
||||||
|
* @param text Unit group name.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
private fun Header(text: String) {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(MaterialTheme.colorScheme.background)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 12.dp, horizontal = 8.dp),
|
||||||
|
text = text,
|
||||||
|
style = MaterialTheme.typography.titleMedium,
|
||||||
|
color = MaterialTheme.colorScheme.primary
|
||||||
)
|
)
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user