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
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import com.sadellie.unitto.R
|
||||
|
||||
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.
|
||||
* 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),
|
||||
CURRENCY(res = R.string.currency),
|
||||
MASS(res = R.string.mass),
|
||||
|
@ -84,17 +84,17 @@ fun SecondScreen(
|
||||
)
|
||||
UnitsList(
|
||||
groupedUnits = unitsList,
|
||||
changeAction = { viewModel.changeUnitFrom(it); focusManager.clearFocus(true); navigateUp() },
|
||||
selectAction = { viewModel.changeUnitFrom(it); focusManager.clearFocus(true); navigateUp() },
|
||||
favoriteAction = { viewModel.favoriteUnit(it) },
|
||||
currentUnit = viewModel.unitFrom,
|
||||
)
|
||||
} else {
|
||||
UnitsList(
|
||||
groupedUnits = unitsList,
|
||||
changeAction = { viewModel.changeUnitTo(it); focusManager.clearFocus(true); navigateUp() },
|
||||
selectAction = { viewModel.changeUnitTo(it); focusManager.clearFocus(true); navigateUp() },
|
||||
favoriteAction = { viewModel.favoriteUnit(it) },
|
||||
currentUnit = viewModel.unitTo,
|
||||
inputValue = viewModel.mainUIState.inputValue.toBigDecimal(),
|
||||
input = viewModel.mainUIState.inputValue.toBigDecimal(),
|
||||
unitFrom = viewModel.unitFrom
|
||||
)
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
@ -40,34 +39,29 @@ import com.sadellie.unitto.R
|
||||
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 changeAction Function to change current unit. Called when choosing unit
|
||||
* @param favoriteAction Function to mark unit as favorite. It's a toggle
|
||||
* @param item The unit itself
|
||||
* @param isSelected Whether this unit is selected or not (current pair of unit)
|
||||
* @param convertValue Used for right side units. Shows conversion from unit on the left
|
||||
* @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 shortNameLabel String on the second line.
|
||||
*/
|
||||
@Composable
|
||||
fun UnitListItem(
|
||||
modifier: Modifier,
|
||||
changeAction: (AbstractUnit) -> Unit,
|
||||
favoriteAction: (AbstractUnit) -> Unit,
|
||||
item: AbstractUnit,
|
||||
private fun BasicUnitListItem(
|
||||
unit: AbstractUnit,
|
||||
isSelected: Boolean,
|
||||
convertValue: (AbstractUnit) -> String
|
||||
selectAction: (AbstractUnit) -> Unit,
|
||||
favoriteAction: (AbstractUnit) -> Unit,
|
||||
shortNameLabel: String
|
||||
) {
|
||||
var isFavorite: Boolean by rememberSaveable { mutableStateOf(item.isFavorite) }
|
||||
var convertedValue: String by remember { mutableStateOf("") }
|
||||
var isFavorite: Boolean by rememberSaveable { mutableStateOf(unit.isFavorite) }
|
||||
Box(
|
||||
modifier = modifier
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = rememberRipple(), // You can also change the color and radius of the ripple
|
||||
onClick = {
|
||||
changeAction(item)
|
||||
}
|
||||
onClick = { selectAction(unit) }
|
||||
)
|
||||
.padding(horizontal = 12.dp)
|
||||
) {
|
||||
@ -87,19 +81,19 @@ fun UnitListItem(
|
||||
.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = item.displayName),
|
||||
text = stringResource(id = unit.displayName),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Text(
|
||||
text = convertedValue + stringResource(id = item.shortName),
|
||||
text = shortNameLabel,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
IconButton(onClick = { favoriteAction(item); isFavorite = !isFavorite }) {
|
||||
IconButton(onClick = { favoriteAction(unit); isFavorite = !isFavorite }) {
|
||||
AnimatedContent(
|
||||
targetState = isFavorite,
|
||||
transitionSpec = {
|
||||
@ -107,15 +101,57 @@ fun UnitListItem(
|
||||
}
|
||||
) {
|
||||
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)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 changeAction Action to perform when clicking on a 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 unitFrom Current unit on the left. Used for right side screen
|
||||
* @param currentUnit Currently selected unit. Will be visually distinguishable
|
||||
* @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.
|
||||
*/
|
||||
@Composable
|
||||
fun UnitsList(
|
||||
groupedUnits: Map<UnitGroup, List<AbstractUnit>>,
|
||||
changeAction: (AbstractUnit) -> Unit,
|
||||
selectAction: (AbstractUnit) -> Unit,
|
||||
favoriteAction: (AbstractUnit) -> Unit,
|
||||
inputValue: BigDecimal = BigDecimal.ONE,
|
||||
unitFrom: AbstractUnit? = null,
|
||||
currentUnit: AbstractUnit,
|
||||
) {
|
||||
LazyColumn(
|
||||
@ -42,41 +38,82 @@ fun UnitsList(
|
||||
content = {
|
||||
if (groupedUnits.isEmpty()) {
|
||||
item { SearchPlaceholder() }
|
||||
} else {
|
||||
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
|
||||
)
|
||||
}
|
||||
items(items = listOfUnits, key = { it.unitId }) { unit ->
|
||||
UnitListItem(
|
||||
modifier = Modifier,
|
||||
changeAction = changeAction,
|
||||
favoriteAction = favoriteAction,
|
||||
item = unit,
|
||||
isSelected = currentUnit == unit,
|
||||
convertValue = {
|
||||
if (unitFrom != null) {
|
||||
Formatter.format(
|
||||
unitFrom
|
||||
.convert(it, inputValue, 3)
|
||||
.toPlainString()
|
||||
).plus(" ")
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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