mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-18 16:25:27 +02:00
Bumped dependencies really hard this time
This commit is contained in:
parent
83f092fb7c
commit
49f1520d88
@ -90,9 +90,6 @@ android {
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_11.toString()
|
||||
freeCompilerArgs = freeCompilerArgs + listOf(
|
||||
"-opt-in=androidx.lifecycle.compose.ExperimentalLifecycleComposeApi"
|
||||
)
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
|
@ -73,7 +73,6 @@ internal fun Project.configureKotlinAndroid(
|
||||
"-opt-in=androidx.compose.animation.ExperimentalAnimationApi",
|
||||
"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
|
||||
"-opt-in=androidx.compose.ui.unit.ExperimentalUnitApi",
|
||||
"-opt-in=androidx.lifecycle.compose.ExperimentalLifecycleComposeApi",
|
||||
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
|
||||
)
|
||||
jvmTarget = JavaVersion.VERSION_11.toString()
|
||||
|
@ -16,8 +16,6 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@file:Suppress("UnstableApiUsage")
|
||||
|
||||
plugins {
|
||||
id("unitto.library")
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
package com.sadellie.unitto.core.base
|
||||
|
||||
@Suppress("ObjectPropertyName")
|
||||
object Token {
|
||||
object Digit {
|
||||
const val _1 = "1"
|
||||
|
@ -117,5 +117,42 @@ fun <T1, T2, T3, T4, T5, T6, T7, T8, R> combine(
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST", "UNUSED")
|
||||
fun <T1, T2, T3, T4, T5, T6, T7, T8, T9, R> combine(
|
||||
flow: Flow<T1>,
|
||||
flow2: Flow<T2>,
|
||||
flow3: Flow<T3>,
|
||||
flow4: Flow<T4>,
|
||||
flow5: Flow<T5>,
|
||||
flow6: Flow<T6>,
|
||||
flow7: Flow<T7>,
|
||||
flow8: Flow<T8>,
|
||||
flow9: Flow<T9>,
|
||||
transform: suspend (T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R,
|
||||
): Flow<R> =
|
||||
kotlinx.coroutines.flow.combine(
|
||||
flow,
|
||||
flow2,
|
||||
flow3,
|
||||
flow4,
|
||||
flow5,
|
||||
flow6,
|
||||
flow7,
|
||||
flow8,
|
||||
flow9
|
||||
) { args: Array<*> ->
|
||||
transform(
|
||||
args[0] as T1,
|
||||
args[1] as T2,
|
||||
args[2] as T3,
|
||||
args[3] as T4,
|
||||
args[4] as T5,
|
||||
args[5] as T6,
|
||||
args[6] as T7,
|
||||
args[7] as T8,
|
||||
args[8] as T9,
|
||||
)
|
||||
}
|
||||
|
||||
fun <T> Flow<T>.stateIn(scope: CoroutineScope, initialValue: T): StateFlow<T> =
|
||||
stateIn(scope, SharingStarted.WhileSubscribed(5000L), initialValue)
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
package io.github.sadellie.evaluatto
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertThrows
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
|
||||
|
@ -245,7 +245,7 @@ class UnitsRepository @Inject constructor(
|
||||
favoritesOnly: Boolean,
|
||||
hideBrokenUnits: Boolean,
|
||||
sorting: UnitsListSorting,
|
||||
shownUnitGroups: List<UnitGroup>,
|
||||
shownUnitGroups: List<UnitGroup> = emptyList(),
|
||||
): Map<UnitGroup, List<AbstractUnit>> {
|
||||
// Leave only shown unit groups
|
||||
var units: Sequence<AbstractUnit> = if (unitGroup == null) {
|
||||
|
@ -45,7 +45,6 @@ import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.getAndUpdate
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
@ -73,8 +72,13 @@ internal class ConverterViewModel @Inject constructor(
|
||||
private val _unitFrom = MutableStateFlow<AbstractUnit?>(null)
|
||||
private val _unitTo = MutableStateFlow<AbstractUnit?>(null)
|
||||
|
||||
private val _leftSideUIState = MutableStateFlow(LeftSideUIState())
|
||||
private val _rightSideUIState = MutableStateFlow(RightSideUIState())
|
||||
private val _leftQuery = MutableStateFlow(TextFieldValue())
|
||||
private val _leftUnits = MutableStateFlow<Map<UnitGroup, List<AbstractUnit>>>(emptyMap())
|
||||
private val _leftUnitGroup = MutableStateFlow<UnitGroup?>(null)
|
||||
|
||||
private val _rightQuery = MutableStateFlow(TextFieldValue())
|
||||
private val _rightUnits = MutableStateFlow<Map<UnitGroup, List<AbstractUnit>>>(emptyMap())
|
||||
|
||||
private val _currenciesState = MutableStateFlow<CurrencyRateUpdateState>(CurrencyRateUpdateState.Nothing)
|
||||
private var _loadCurrenciesJob: Job? = null
|
||||
|
||||
@ -153,19 +157,28 @@ internal class ConverterViewModel @Inject constructor(
|
||||
|
||||
val leftSideUIState = combine(
|
||||
_unitFrom,
|
||||
_leftSideUIState,
|
||||
_leftQuery,
|
||||
_leftUnits,
|
||||
_leftUnitGroup,
|
||||
userPrefsRepository.converterPrefs,
|
||||
unitsRepo.allUnits
|
||||
) { unitFrom, ui, prefs, _ ->
|
||||
return@combine ui.copy(
|
||||
) { unitFrom, query, units, unitGroup, prefs, _ ->
|
||||
unitFrom ?: return@combine LeftSideUIState.Loading
|
||||
|
||||
return@combine LeftSideUIState.Ready(
|
||||
unitFrom = unitFrom,
|
||||
sorting = prefs.unitConverterSorting,
|
||||
shownUnitGroups = prefs.shownUnitGroups,
|
||||
favorites = prefs.unitConverterFavoritesOnly,
|
||||
verticalList = prefs.enableToolsExperiment,
|
||||
query = query,
|
||||
units = units,
|
||||
unitGroup = unitGroup
|
||||
)
|
||||
}
|
||||
.mapLatest {
|
||||
if (it !is LeftSideUIState.Ready) return@mapLatest it
|
||||
|
||||
filterUnitsLeft(
|
||||
query = it.query,
|
||||
unitGroup = it.unitGroup,
|
||||
@ -175,19 +188,23 @@ internal class ConverterViewModel @Inject constructor(
|
||||
)
|
||||
it
|
||||
}
|
||||
.stateIn(viewModelScope, SharingStarted.Lazily, LeftSideUIState())
|
||||
.stateIn(viewModelScope, SharingStarted.Lazily, LeftSideUIState.Loading)
|
||||
|
||||
val rightSideUIState = combine(
|
||||
_unitFrom,
|
||||
_unitTo,
|
||||
_input,
|
||||
_calculation,
|
||||
_rightSideUIState,
|
||||
_rightQuery,
|
||||
_rightUnits,
|
||||
userPrefsRepository.converterPrefs,
|
||||
_currenciesState,
|
||||
unitsRepo.allUnits,
|
||||
) { unitFrom, unitTo, input, calculation, ui, prefs, currenciesState, _ ->
|
||||
return@combine ui.copy(
|
||||
) { unitFrom, unitTo, input, calculation, query, units, prefs, currenciesState, _ ->
|
||||
unitFrom ?: return@combine RightSideUIState.Loading
|
||||
unitTo ?: return@combine RightSideUIState.Loading
|
||||
|
||||
return@combine RightSideUIState.Ready(
|
||||
unitFrom = unitFrom,
|
||||
unitTo = unitTo,
|
||||
sorting = prefs.unitConverterSorting,
|
||||
@ -196,20 +213,23 @@ internal class ConverterViewModel @Inject constructor(
|
||||
scale = prefs.precision,
|
||||
outputFormat = prefs.outputFormat,
|
||||
formatterSymbols = AllFormatterSymbols.getById(prefs.separator),
|
||||
currencyRateUpdateState = currenciesState
|
||||
currencyRateUpdateState = currenciesState,
|
||||
query = query,
|
||||
units = units,
|
||||
)
|
||||
}
|
||||
.mapLatest {
|
||||
if (it !is RightSideUIState.Ready) return@mapLatest it
|
||||
|
||||
filterUnitsRight(
|
||||
query = it.query,
|
||||
unitGroup = it.unitTo?.group,
|
||||
unitGroup = it.unitTo.group,
|
||||
favoritesOnly = it.favorites,
|
||||
sorting = it.sorting,
|
||||
shownUnitGroups = emptyList(),
|
||||
)
|
||||
it
|
||||
}
|
||||
.stateIn(viewModelScope, SharingStarted.Lazily, RightSideUIState())
|
||||
.stateIn(viewModelScope, SharingStarted.Lazily, RightSideUIState.Loading)
|
||||
|
||||
fun swapUnits() {
|
||||
_unitFrom
|
||||
@ -303,21 +323,15 @@ internal class ConverterViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun queryChangeLeft(query: TextFieldValue) = _leftSideUIState.update {
|
||||
it.copy(query = query)
|
||||
}
|
||||
fun queryChangeLeft(query: TextFieldValue) = _leftQuery.update { query }
|
||||
|
||||
fun queryChangeRight(query: TextFieldValue) = _rightSideUIState.update {
|
||||
it.copy(query = query)
|
||||
}
|
||||
fun queryChangeRight(query: TextFieldValue) = _rightQuery.update { query }
|
||||
|
||||
fun favoritesOnlyChange(enabled: Boolean) = viewModelScope.launch {
|
||||
userPrefsRepository.updateUnitConverterFavoritesOnly(enabled)
|
||||
}
|
||||
|
||||
fun updateUnitGroupLeft(unitGroup: UnitGroup?) = _leftSideUIState.update {
|
||||
it.copy(unitGroup = unitGroup)
|
||||
}
|
||||
fun updateUnitGroupLeft(unitGroup: UnitGroup?) = _leftUnitGroup.update { unitGroup }
|
||||
|
||||
fun favoriteUnit(unit: AbstractUnit) = viewModelScope.launch {
|
||||
unitsRepo.favorite(unit)
|
||||
@ -330,9 +344,8 @@ internal class ConverterViewModel @Inject constructor(
|
||||
sorting: UnitsListSorting,
|
||||
shownUnitGroups: List<UnitGroup>,
|
||||
) = viewModelScope.launch(Dispatchers.Default) {
|
||||
_leftSideUIState.update {
|
||||
it.copy(
|
||||
units = unitsRepo.filterUnits(
|
||||
_leftUnits.update {
|
||||
unitsRepo.filterUnits(
|
||||
query = query.text,
|
||||
unitGroup = unitGroup,
|
||||
favoritesOnly = favoritesOnly,
|
||||
@ -340,7 +353,6 @@ internal class ConverterViewModel @Inject constructor(
|
||||
sorting = sorting,
|
||||
shownUnitGroups = shownUnitGroups
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -349,18 +361,14 @@ internal class ConverterViewModel @Inject constructor(
|
||||
unitGroup: UnitGroup?,
|
||||
favoritesOnly: Boolean,
|
||||
sorting: UnitsListSorting,
|
||||
shownUnitGroups: List<UnitGroup>,
|
||||
) = viewModelScope.launch(Dispatchers.Default) {
|
||||
_rightSideUIState.update {
|
||||
it.copy(
|
||||
units = unitsRepo.filterUnits(
|
||||
_rightUnits.update {
|
||||
unitsRepo.filterUnits(
|
||||
query = query.text,
|
||||
unitGroup = unitGroup,
|
||||
favoritesOnly = favoritesOnly,
|
||||
hideBrokenUnits = true,
|
||||
sorting = sorting,
|
||||
shownUnitGroups = shownUnitGroups
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.core.LinearOutSlowInEasing
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@ -49,13 +50,17 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.sadellie.unitto.core.base.R
|
||||
import com.sadellie.unitto.core.ui.common.UnittoSearchBar
|
||||
import com.sadellie.unitto.data.model.UnitGroup
|
||||
import com.sadellie.unitto.data.model.UnitsListSorting
|
||||
import com.sadellie.unitto.data.model.unit.AbstractUnit
|
||||
import com.sadellie.unitto.data.model.unit.NormalUnit
|
||||
import com.sadellie.unitto.data.units.MyUnitIDS
|
||||
import com.sadellie.unitto.feature.converter.components.BasicUnitListItem
|
||||
import com.sadellie.unitto.feature.converter.components.ChipsFlexRow
|
||||
import com.sadellie.unitto.feature.converter.components.ChipsRow
|
||||
import com.sadellie.unitto.feature.converter.components.FavoritesButton
|
||||
import com.sadellie.unitto.feature.converter.components.SearchPlaceholder
|
||||
import com.sadellie.unitto.feature.converter.components.UnitGroupHeader
|
||||
import java.math.BigDecimal
|
||||
|
||||
@Composable
|
||||
internal fun LeftSideRoute(
|
||||
@ -63,10 +68,14 @@ internal fun LeftSideRoute(
|
||||
navigateUp: () -> Unit,
|
||||
navigateToUnitGroups: () -> Unit,
|
||||
) {
|
||||
val uiState = viewModel.leftSideUIState.collectAsStateWithLifecycle()
|
||||
|
||||
LeftSideScreen(
|
||||
uiState = uiState.value,
|
||||
when (
|
||||
val uiState = viewModel.leftSideUIState.collectAsStateWithLifecycle().value
|
||||
) {
|
||||
is LeftSideUIState.Loading -> {
|
||||
Box(modifier = Modifier.fillMaxSize())
|
||||
}
|
||||
is LeftSideUIState.Ready -> LeftSideScreen(
|
||||
uiState = uiState,
|
||||
onQueryChange = viewModel::queryChangeLeft,
|
||||
toggleFavoritesOnly = viewModel::favoritesOnlyChange,
|
||||
updateUnitFrom = viewModel::updateUnitFrom,
|
||||
@ -76,10 +85,11 @@ internal fun LeftSideRoute(
|
||||
navigateToUnitGroups = navigateToUnitGroups,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LeftSideScreen(
|
||||
uiState: LeftSideUIState,
|
||||
uiState: LeftSideUIState.Ready,
|
||||
onQueryChange: (TextFieldValue) -> Unit,
|
||||
toggleFavoritesOnly: (Boolean) -> Unit,
|
||||
updateUnitFrom: (AbstractUnit) -> Unit,
|
||||
@ -102,13 +112,12 @@ private fun LeftSideScreen(
|
||||
val chipsRowLazyListState = rememberLazyListState()
|
||||
|
||||
LaunchedEffect(uiState.unitFrom, uiState.shownUnitGroups) {
|
||||
if (uiState.unitFrom == null) return@LaunchedEffect
|
||||
updateUnitGroup(uiState.unitFrom.group)
|
||||
|
||||
kotlin.runCatching {
|
||||
val groupToSelect = uiState.shownUnitGroups.indexOf(uiState.unitFrom.group)
|
||||
if (groupToSelect > -1) {
|
||||
kotlin.runCatching {
|
||||
chipsRowLazyListState.animateScrollToItem(groupToSelect)
|
||||
chipsRowLazyListState.scrollToItem(groupToSelect)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -153,13 +162,13 @@ private fun LeftSideScreen(
|
||||
}
|
||||
) { paddingValues ->
|
||||
Crossfade(
|
||||
targetState = uiState.units?.isNotEmpty(),
|
||||
targetState = uiState.units.isNotEmpty(),
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
label = "Units list"
|
||||
) { hasUnits ->
|
||||
when (hasUnits) {
|
||||
true -> LazyColumn(Modifier.fillMaxSize()) {
|
||||
uiState.units?.forEach { (unitGroup, units) ->
|
||||
uiState.units.forEach { (unitGroup, units) ->
|
||||
item(unitGroup.name) {
|
||||
UnitGroupHeader(Modifier.animateItemPlacement(), unitGroup)
|
||||
}
|
||||
@ -170,7 +179,7 @@ private fun LeftSideScreen(
|
||||
name = stringResource(it.displayName),
|
||||
supportLabel = stringResource(it.shortName),
|
||||
isFavorite = it.isFavorite,
|
||||
isSelected = it.id == uiState.unitFrom?.id,
|
||||
isSelected = it.id == uiState.unitFrom.id,
|
||||
onClick = {
|
||||
onQueryChange(TextFieldValue())
|
||||
updateUnitFrom(it)
|
||||
@ -183,7 +192,6 @@ private fun LeftSideScreen(
|
||||
}
|
||||
|
||||
false -> SearchPlaceholder(navigateToSettingsAction = navigateToUnitGroups)
|
||||
null -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -192,8 +200,29 @@ private fun LeftSideScreen(
|
||||
@Preview
|
||||
@Composable
|
||||
private fun LeftSideScreenPreview() {
|
||||
val units: Map<UnitGroup, List<AbstractUnit>> = mapOf(
|
||||
UnitGroup.LENGTH to listOf(
|
||||
NormalUnit(MyUnitIDS.meter, BigDecimal.valueOf(1.0E+18), UnitGroup.LENGTH, R.string.meter, R.string.meter_short),
|
||||
NormalUnit(MyUnitIDS.kilometer, BigDecimal.valueOf(1.0E+21), UnitGroup.LENGTH, R.string.kilometer, R.string.kilometer_short),
|
||||
NormalUnit(MyUnitIDS.nautical_mile, BigDecimal.valueOf(1.852E+21), UnitGroup.LENGTH, R.string.nautical_mile, R.string.nautical_mile_short),
|
||||
NormalUnit(MyUnitIDS.inch, BigDecimal.valueOf(25_400_000_000_000_000), UnitGroup.LENGTH, R.string.inch, R.string.inch_short),
|
||||
NormalUnit(MyUnitIDS.foot, BigDecimal.valueOf(304_800_000_000_002_200), UnitGroup.LENGTH, R.string.foot, R.string.foot_short),
|
||||
NormalUnit(MyUnitIDS.yard, BigDecimal.valueOf(914_400_000_000_006_400), UnitGroup.LENGTH, R.string.yard, R.string.yard_short),
|
||||
NormalUnit(MyUnitIDS.mile, BigDecimal.valueOf(1_609_344_000_000_010_500_000.0), UnitGroup.LENGTH, R.string.mile, R.string.mile_short),
|
||||
)
|
||||
)
|
||||
|
||||
LeftSideScreen(
|
||||
uiState = LeftSideUIState(),
|
||||
uiState = LeftSideUIState.Ready(
|
||||
unitFrom = units.values.first().first(),
|
||||
units = units,
|
||||
query = TextFieldValue(),
|
||||
favorites = false,
|
||||
shownUnitGroups = listOf(UnitGroup.LENGTH, UnitGroup.TEMPERATURE, UnitGroup.CURRENCY),
|
||||
unitGroup = units.keys.toList().first(),
|
||||
sorting = UnitsListSorting.USAGE,
|
||||
verticalList = false
|
||||
),
|
||||
onQueryChange = {},
|
||||
toggleFavoritesOnly = {},
|
||||
updateUnitFrom = {},
|
||||
|
@ -23,13 +23,17 @@ import com.sadellie.unitto.data.model.UnitGroup
|
||||
import com.sadellie.unitto.data.model.UnitsListSorting
|
||||
import com.sadellie.unitto.data.model.unit.AbstractUnit
|
||||
|
||||
internal data class LeftSideUIState(
|
||||
val unitFrom: AbstractUnit? = null,
|
||||
val query: TextFieldValue = TextFieldValue(),
|
||||
val units: Map<UnitGroup, List<AbstractUnit>>? = null,
|
||||
val favorites: Boolean = false,
|
||||
val shownUnitGroups: List<UnitGroup> = emptyList(),
|
||||
val unitGroup: UnitGroup? = unitFrom?.group,
|
||||
val sorting: UnitsListSorting = UnitsListSorting.USAGE,
|
||||
val verticalList: Boolean = false,
|
||||
)
|
||||
internal sealed class LeftSideUIState {
|
||||
data object Loading : LeftSideUIState()
|
||||
|
||||
data class Ready(
|
||||
val unitFrom: AbstractUnit,
|
||||
val query: TextFieldValue,
|
||||
val units: Map<UnitGroup, List<AbstractUnit>> = emptyMap(),
|
||||
val favorites: Boolean,
|
||||
val shownUnitGroups: List<UnitGroup>,
|
||||
val unitGroup: UnitGroup?,
|
||||
val sorting: UnitsListSorting,
|
||||
val verticalList: Boolean,
|
||||
) : LeftSideUIState()
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
package com.sadellie.unitto.feature.converter
|
||||
|
||||
import androidx.compose.animation.Crossfade
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
@ -33,15 +34,19 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.sadellie.unitto.core.base.OutputFormat
|
||||
import com.sadellie.unitto.core.base.R
|
||||
import com.sadellie.unitto.core.ui.common.UnittoSearchBar
|
||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
||||
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
||||
import com.sadellie.unitto.data.common.format
|
||||
import com.sadellie.unitto.data.model.UnitGroup
|
||||
import com.sadellie.unitto.data.model.UnitsListSorting
|
||||
import com.sadellie.unitto.data.model.unit.AbstractUnit
|
||||
import com.sadellie.unitto.data.model.unit.DefaultUnit
|
||||
import com.sadellie.unitto.data.model.unit.NormalUnit
|
||||
import com.sadellie.unitto.data.model.unit.NumberBaseUnit
|
||||
import com.sadellie.unitto.data.units.MyUnitIDS
|
||||
import com.sadellie.unitto.feature.converter.components.BasicUnitListItem
|
||||
import com.sadellie.unitto.feature.converter.components.FavoritesButton
|
||||
import com.sadellie.unitto.feature.converter.components.SearchPlaceholder
|
||||
@ -54,10 +59,13 @@ internal fun RightSideRoute(
|
||||
navigateUp: () -> Unit,
|
||||
navigateToUnitGroups: () -> Unit,
|
||||
) {
|
||||
val uiState = viewModel.rightSideUIState.collectAsStateWithLifecycle()
|
||||
|
||||
when (
|
||||
val uiState = viewModel.rightSideUIState.collectAsStateWithLifecycle().value
|
||||
) {
|
||||
is RightSideUIState.Loading -> Box(Modifier.fillMaxSize())
|
||||
is RightSideUIState.Ready ->
|
||||
RightSideScreen(
|
||||
uiState = uiState.value,
|
||||
uiState = uiState,
|
||||
onQueryChange = viewModel::queryChangeRight,
|
||||
toggleFavoritesOnly = viewModel::favoritesOnlyChange,
|
||||
updateUnitTo = viewModel::updateUnitTo,
|
||||
@ -66,10 +74,11 @@ internal fun RightSideRoute(
|
||||
navigateToUnitGroups = navigateToUnitGroups,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RightSideScreen(
|
||||
uiState: RightSideUIState,
|
||||
uiState: RightSideUIState.Ready,
|
||||
onQueryChange: (TextFieldValue) -> Unit,
|
||||
toggleFavoritesOnly: (Boolean) -> Unit,
|
||||
updateUnitTo: (AbstractUnit) -> Unit,
|
||||
@ -98,13 +107,13 @@ private fun RightSideScreen(
|
||||
}
|
||||
) { paddingValues ->
|
||||
Crossfade(
|
||||
targetState = uiState.units?.isNotEmpty(),
|
||||
targetState = uiState.units.isNotEmpty(),
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
label = "Units list"
|
||||
) { hasUnits ->
|
||||
when (hasUnits) {
|
||||
true -> LazyColumn(Modifier.fillMaxSize()) {
|
||||
uiState.units?.forEach { (unitGroup, units) ->
|
||||
uiState.units.forEach { (unitGroup, units) ->
|
||||
item(unitGroup.name) {
|
||||
UnitGroupHeader(Modifier.animateItemPlacement(), unitGroup)
|
||||
}
|
||||
@ -124,7 +133,7 @@ private fun RightSideScreen(
|
||||
readyCurrencies = uiState.currencyRateUpdateState is CurrencyRateUpdateState.Ready,
|
||||
),
|
||||
isFavorite = it.isFavorite,
|
||||
isSelected = it.id == uiState.unitTo?.id,
|
||||
isSelected = it.id == uiState.unitTo.id,
|
||||
onClick = {
|
||||
onQueryChange(TextFieldValue())
|
||||
updateUnitTo(it)
|
||||
@ -137,7 +146,6 @@ private fun RightSideScreen(
|
||||
}
|
||||
|
||||
false -> SearchPlaceholder(navigateToSettingsAction = navigateToUnitGroups)
|
||||
null -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -187,8 +195,32 @@ private fun formatUnitToSupportLabel(
|
||||
@Preview
|
||||
@Composable
|
||||
private fun RightSideScreenPreview() {
|
||||
val units: Map<UnitGroup, List<AbstractUnit>> = mapOf(
|
||||
UnitGroup.LENGTH to listOf(
|
||||
NormalUnit(MyUnitIDS.meter, BigDecimal.valueOf(1.0E+18), UnitGroup.LENGTH, R.string.meter, R.string.meter_short),
|
||||
NormalUnit(MyUnitIDS.kilometer, BigDecimal.valueOf(1.0E+21), UnitGroup.LENGTH, R.string.kilometer, R.string.kilometer_short),
|
||||
NormalUnit(MyUnitIDS.nautical_mile, BigDecimal.valueOf(1.852E+21), UnitGroup.LENGTH, R.string.nautical_mile, R.string.nautical_mile_short),
|
||||
NormalUnit(MyUnitIDS.inch, BigDecimal.valueOf(25_400_000_000_000_000), UnitGroup.LENGTH, R.string.inch, R.string.inch_short),
|
||||
NormalUnit(MyUnitIDS.foot, BigDecimal.valueOf(304_800_000_000_002_200), UnitGroup.LENGTH, R.string.foot, R.string.foot_short),
|
||||
NormalUnit(MyUnitIDS.yard, BigDecimal.valueOf(914_400_000_000_006_400), UnitGroup.LENGTH, R.string.yard, R.string.yard_short),
|
||||
NormalUnit(MyUnitIDS.mile, BigDecimal.valueOf(1_609_344_000_000_010_500_000.0), UnitGroup.LENGTH, R.string.mile, R.string.mile_short),
|
||||
)
|
||||
)
|
||||
|
||||
RightSideScreen(
|
||||
uiState = RightSideUIState(),
|
||||
uiState = RightSideUIState.Ready(
|
||||
unitFrom = units.values.first().first(),
|
||||
units = units,
|
||||
query = TextFieldValue(),
|
||||
favorites = false,
|
||||
sorting = UnitsListSorting.USAGE,
|
||||
unitTo = units.values.first()[1],
|
||||
input = "100",
|
||||
scale = 3,
|
||||
outputFormat = OutputFormat.PLAIN,
|
||||
formatterSymbols = FormatterSymbols.Spaces,
|
||||
currencyRateUpdateState = CurrencyRateUpdateState.Nothing
|
||||
),
|
||||
onQueryChange = {},
|
||||
toggleFavoritesOnly = {},
|
||||
updateUnitTo = {},
|
||||
|
@ -19,23 +19,25 @@
|
||||
package com.sadellie.unitto.feature.converter
|
||||
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import com.sadellie.unitto.core.base.OutputFormat
|
||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
||||
import com.sadellie.unitto.data.model.UnitGroup
|
||||
import com.sadellie.unitto.data.model.UnitsListSorting
|
||||
import com.sadellie.unitto.data.model.unit.AbstractUnit
|
||||
|
||||
internal data class RightSideUIState(
|
||||
val unitFrom: AbstractUnit? = null,
|
||||
val unitTo: AbstractUnit? = null,
|
||||
val query: TextFieldValue = TextFieldValue(),
|
||||
val units: Map<UnitGroup, List<AbstractUnit>>? = null,
|
||||
val favorites: Boolean = false,
|
||||
val unitGroup: UnitGroup? = unitFrom?.group,
|
||||
val sorting: UnitsListSorting = UnitsListSorting.USAGE,
|
||||
val input: String = "",
|
||||
val scale: Int = 3,
|
||||
val outputFormat: Int = OutputFormat.PLAIN,
|
||||
val formatterSymbols: FormatterSymbols = FormatterSymbols.Spaces,
|
||||
val currencyRateUpdateState: CurrencyRateUpdateState = CurrencyRateUpdateState.Nothing
|
||||
)
|
||||
internal sealed class RightSideUIState {
|
||||
data object Loading : RightSideUIState()
|
||||
|
||||
data class Ready(
|
||||
val unitFrom: AbstractUnit,
|
||||
val unitTo: AbstractUnit,
|
||||
val query: TextFieldValue,
|
||||
val units: Map<UnitGroup, List<AbstractUnit>>,
|
||||
val favorites: Boolean,
|
||||
val sorting: UnitsListSorting,
|
||||
val input: String,
|
||||
val scale: Int,
|
||||
val outputFormat: Int,
|
||||
val formatterSymbols: FormatterSymbols,
|
||||
val currencyRateUpdateState: CurrencyRateUpdateState,
|
||||
) : RightSideUIState()
|
||||
}
|
||||
|
@ -6,19 +6,19 @@ ksp = "1.9.0-1.0.13"
|
||||
androidxCore = "1.12.0"
|
||||
androidGradlePlugin = "8.1.1"
|
||||
orgJetbrainsKotlinxCoroutinesTest = "1.7.2"
|
||||
androidxCompose = "1.6.0-alpha05"
|
||||
androidxCompose = "1.6.0-alpha06"
|
||||
androidxComposeCompiler = "1.5.0"
|
||||
androidxComposeUi = "1.6.0-alpha05"
|
||||
androidxComposeMaterial3 = "1.2.0-alpha07"
|
||||
androidxNavigation = "2.7.2"
|
||||
androidxComposeUi = "1.6.0-alpha06"
|
||||
androidxComposeMaterial3 = "1.2.0-alpha08"
|
||||
androidxNavigation = "2.7.3"
|
||||
androidxLifecycleRuntimeCompose = "2.6.2"
|
||||
androidxHilt = "1.0.0"
|
||||
androidxAppCompat = "1.6.1"
|
||||
comGoogleDagger = "2.47"
|
||||
androidxComposeMaterialIconsExtended = "1.6.0-alpha05"
|
||||
androidxComposeMaterialIconsExtended = "1.6.0-alpha06"
|
||||
androidxDatastore = "1.0.0"
|
||||
comGoogleAccompanist = "0.30.1"
|
||||
androidxRoom = "2.6.0-beta01"
|
||||
androidxRoom = "2.6.0-rc01"
|
||||
comSquareupMoshi = "1.15.0"
|
||||
comSquareupRetrofit2 = "2.9.0"
|
||||
comGithubSadellieThemmo = "1.0.0"
|
||||
|
Loading…
x
Reference in New Issue
Block a user