From 4354d006529f3ef00c64e22041f4c2c24fee7ade Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Fri, 2 Jun 2023 16:52:04 +0300 Subject: [PATCH] I have no idea what i'm doing --- .../unitto/data/model/AbstractUnit.kt | 2 -- .../sadellie/unitto/data/model/DefaultUnit.kt | 3 +++ .../unitto/data/units/AllUnitsRepository.kt | 27 ++++++++++--------- .../data/units/AllUnitsRepositoryTest.kt | 15 ++++++----- .../feature/converter/ConverterViewModel.kt | 6 +---- .../feature/unitslist/LeftSideScreen.kt | 10 +++---- .../feature/unitslist/RightSideScreen.kt | 6 ++--- .../feature/unitslist/UnitsListViewModel.kt | 23 ++++++++-------- .../navigation/UnitsListNavigation.kt | 2 +- 9 files changed, 46 insertions(+), 48 deletions(-) diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/AbstractUnit.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/AbstractUnit.kt index 3e663423..8ee9aae4 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/AbstractUnit.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/AbstractUnit.kt @@ -37,7 +37,6 @@ import java.math.BigDecimal * @property renderedShortName Used as cache. Stores short name string for this specific device. Need for * search functionality. * @property isFavorite Whether this unit is favorite. - * @property isEnabled Whether we need to show this unit or not * @property pairedUnit Latest paired unit on the right * @property counter The amount of time this unit was chosen */ @@ -50,7 +49,6 @@ abstract class AbstractUnit( var renderedName: String = String(), var renderedShortName: String = String(), var isFavorite: Boolean = false, - var isEnabled: Boolean = true, var pairedUnit: String? = null, var counter: Int = 0 ) { diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/DefaultUnit.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/DefaultUnit.kt index 789158c6..b37a6e01 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/DefaultUnit.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/DefaultUnit.kt @@ -50,6 +50,9 @@ class DefaultUnit( value: BigDecimal, scale: Int ): BigDecimal { + // Avoid division by zero + if (unitTo.basicUnit.compareTo(BigDecimal.ZERO) == 0) return BigDecimal.ZERO + return this .basicUnit .setScale(MAX_PRECISION) diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt index 83e22057..4680e432 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt @@ -48,6 +48,9 @@ import com.sadellie.unitto.data.units.collections.temperatureCollection import com.sadellie.unitto.data.units.collections.timeCollection import com.sadellie.unitto.data.units.collections.torqueCollection import com.sadellie.unitto.data.units.collections.volumeCollection +import com.sadellie.unitto.data.units.remote.CurrencyApi +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import java.math.BigDecimal import javax.inject.Inject import javax.inject.Singleton @@ -123,8 +126,8 @@ class AllUnitsRepository @Inject constructor() { /** * Filter [AllUnitsRepository.allUnits] and group them. * - * @param hideBrokenCurrencies When set to True will remove [AbstractUnit]s that have - * [AbstractUnit.isEnabled] set to False, which means that [AbstractUnit] can not be used. + * @param hideBrokenUnits When set to True will remove [AbstractUnit]s that have + * [AbstractUnit.basicUnit] set to [BigDecimal.ZERO] (comes from currencies API). * @param chosenUnitGroup If provided will scope list to a specific [UnitGroup]. * @param favoritesOnly When True will filter only [AbstractUnit]s with [AbstractUnit.isFavorite] * set to True. @@ -135,7 +138,7 @@ class AllUnitsRepository @Inject constructor() { * @return Grouped by [UnitGroup] list of [AbstractUnit]s. */ fun filterUnits( - hideBrokenCurrencies: Boolean, + hideBrokenUnits: Boolean, chosenUnitGroup: UnitGroup?, favoritesOnly: Boolean, searchQuery: String, @@ -153,8 +156,8 @@ class AllUnitsRepository @Inject constructor() { if (favoritesOnly) { units = units.filter { it.isFavorite } } - if (hideBrokenCurrencies) { - units = units.filter { it.isEnabled } + if (hideBrokenUnits) { + units = units.filter { it.basicUnit > BigDecimal.ZERO } } units = when (sorting) { @@ -198,22 +201,20 @@ class AllUnitsRepository @Inject constructor() { /** * Update [AbstractUnit.basicUnit] properties for currencies from [currencyCollection]. * - * @param conversions Map: [AbstractUnit.unitId] and [BigDecimal] that will replace current - * [AbstractUnit.basicUnit]. + * @param unitFrom Base unit */ - fun updateBasicUnitsForCurrencies( - conversions: Map - ) { + suspend fun updateBasicUnitsForCurrencies( + unitFrom: AbstractUnit + ) = withContext(Dispatchers.IO) { + val conversions: Map = CurrencyApi.retrofitService.getCurrencyPairs(unitFrom.unitId).currency getCollectionByGroup(UnitGroup.CURRENCY).forEach { // Getting rates from map. We set ZERO as default so that it can be skipped val rate = conversions.getOrElse(it.unitId) { BigDecimal.ZERO } // We make sure that we don't divide by zero if (rate > BigDecimal.ZERO) { - it.isEnabled = true it.basicUnit = BigDecimal.ONE.setScale(MAX_PRECISION).div(rate) } else { - // Hiding broken currencies - it.isEnabled = false + it.basicUnit = BigDecimal.ZERO } } } diff --git a/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsRepositoryTest.kt b/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsRepositoryTest.kt index 6973c59b..ab6b2a74 100644 --- a/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsRepositoryTest.kt +++ b/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsRepositoryTest.kt @@ -23,6 +23,7 @@ import com.sadellie.unitto.data.model.AbstractUnit import com.sadellie.unitto.data.model.UnitGroup import org.junit.Assert.assertEquals import org.junit.Test +import java.math.BigDecimal class AllUnitsRepositoryTest { @@ -34,7 +35,7 @@ class AllUnitsRepositoryTest { fun filterAllUnitsNoFiltersLeft() { // No filters applied, empty search query, from Left side list val result = allUnitsRepository.filterUnits( - hideBrokenCurrencies = false, + hideBrokenUnits = false, chosenUnitGroup = null, favoritesOnly = false, searchQuery = "", @@ -51,7 +52,7 @@ class AllUnitsRepositoryTest { // All filters applied, from Left side list val result = allUnitsRepository.filterUnits( - hideBrokenCurrencies = false, + hideBrokenUnits = false, chosenUnitGroup = UnitGroup.SPEED, favoritesOnly = true, searchQuery = "kilometer per hour", @@ -68,7 +69,7 @@ class AllUnitsRepositoryTest { fun filterAllUnitsChosenGroupLeft() { // Only specific group is needed, left side screen val result = allUnitsRepository.filterUnits( - hideBrokenCurrencies = false, + hideBrokenUnits = false, chosenUnitGroup = UnitGroup.TIME, favoritesOnly = false, searchQuery = "", @@ -83,7 +84,7 @@ class AllUnitsRepositoryTest { allUnitsRepository.getById(MyUnitIDS.kilometer).isFavorite = true // Only favorite units, left side screen val result = allUnitsRepository.filterUnits( - hideBrokenCurrencies = false, + hideBrokenUnits = false, chosenUnitGroup = null, favoritesOnly = true, searchQuery = "", @@ -101,7 +102,7 @@ class AllUnitsRepositoryTest { // Only search query is entered, other filters are not set, left side screen val result = allUnitsRepository.filterUnits( - hideBrokenCurrencies = false, + hideBrokenUnits = false, chosenUnitGroup = null, favoritesOnly = false, searchQuery = "kilometer per hour", @@ -118,10 +119,10 @@ class AllUnitsRepositoryTest { fun filterAllUnitsHideBrokenCurrencies() { allUnitsRepository .getById(MyUnitIDS.currency_btc) - .apply { isEnabled = false } + .apply { basicUnit = BigDecimal.ZERO } // Hide broken currencies (i.e. cannot be used for conversion at the moment) val result = allUnitsRepository.filterUnits( - hideBrokenCurrencies = true, + hideBrokenUnits = true, chosenUnitGroup = UnitGroup.CURRENCY, favoritesOnly = false, searchQuery = "", diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterViewModel.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterViewModel.kt index 15bc07a3..dcd62cbd 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterViewModel.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterViewModel.kt @@ -37,8 +37,6 @@ import com.sadellie.unitto.data.model.UnitGroup import com.sadellie.unitto.data.units.AllUnitsRepository import com.sadellie.unitto.data.units.MyUnitIDS import com.sadellie.unitto.data.units.combine -import com.sadellie.unitto.data.units.remote.CurrencyApi -import com.sadellie.unitto.data.units.remote.CurrencyUnitResponse import com.sadellie.unitto.data.userprefs.MainPreferences import com.sadellie.unitto.data.userprefs.UserPreferencesRepository import dagger.hilt.android.lifecycle.HiltViewModel @@ -298,9 +296,7 @@ class ConverterViewModel @Inject constructor( _showLoading.update { true } try { - val pairs: CurrencyUnitResponse = - CurrencyApi.retrofitService.getCurrencyPairs(unitFrom.unitId) - allUnitsRepository.updateBasicUnitsForCurrencies(pairs.currency) + allUnitsRepository.updateBasicUnitsForCurrencies(unitFrom) convertAsExpression() } catch (e: Exception) { // Dangerous and stupid, but who cares diff --git a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/LeftSideScreen.kt b/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/LeftSideScreen.kt index 3ed76063..44531ac2 100644 --- a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/LeftSideScreen.kt +++ b/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/LeftSideScreen.kt @@ -94,9 +94,9 @@ internal fun LeftSideScreen( SearchBar( title = stringResource(R.string.units_screen_from), value = uiState.value.searchQuery, - onValueChange = { viewModel.onSearchQueryChange(it) }, + onValueChange = { viewModel.onSearchQueryChange(it, false) }, favoritesOnly = uiState.value.favoritesOnly, - favoriteAction = { viewModel.toggleFavoritesOnly() }, + favoriteAction = { viewModel.toggleFavoritesOnly(false) }, navigateUpAction = navigateUp, focusManager = focusManager, scrollBehavior = scrollBehavior @@ -104,7 +104,7 @@ internal fun LeftSideScreen( ChipsRow( chosenUnitGroup = uiState.value.chosenUnitGroup, items = uiState.value.shownUnitGroups, - selectAction = { viewModel.toggleSelectedChip(it) }, + selectAction = { viewModel.toggleSelectedChip(it, false) }, lazyListState = chipsRowLazyListState, navigateToSettingsAction = navigateToSettingsAction ) @@ -130,7 +130,7 @@ internal fun LeftSideScreen( isSelected = currentUnitId == unit.unitId, selectAction = { selectAction(it) - viewModel.onSearchQueryChange("") + viewModel.onSearchQueryChange("", false) focusManager.clearFocus(true) navigateUp() }, @@ -147,7 +147,7 @@ internal fun LeftSideScreen( if (currentUnitId == null) return@LaunchedEffect // This is still wrong, but works good enough. // Ideally we shouldn't use uiState.value.shownUnitGroups - viewModel.setSelectedChip(currentUnitId) + viewModel.setSelectedChip(currentUnitId, false) val groupToSelect = uiState.value.shownUnitGroups.indexOf(uiState.value.chosenUnitGroup) if (groupToSelect > -1) { chipsRowLazyListState.animateScrollToItem(groupToSelect) diff --git a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/RightSideScreen.kt b/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/RightSideScreen.kt index e07e3eee..d334d101 100644 --- a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/RightSideScreen.kt +++ b/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/RightSideScreen.kt @@ -96,11 +96,11 @@ internal fun RightSideScreen( title = stringResource(R.string.units_screen_to), value = uiState.value.searchQuery, onValueChange = { - viewModel.onSearchQueryChange(it, false) + viewModel.onSearchQueryChange(it, true) }, favoritesOnly = uiState.value.favoritesOnly, favoriteAction = { - viewModel.toggleFavoritesOnly(false) + viewModel.toggleFavoritesOnly(true) }, navigateUpAction = navigateUp, focusManager = focusManager, @@ -127,7 +127,7 @@ internal fun RightSideScreen( isSelected = currentUnit == unit.unitId, selectAction = { selectAction(it) - viewModel.onSearchQueryChange("") + viewModel.onSearchQueryChange("", true) focusManager.clearFocus(true) navigateUp() }, diff --git a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/UnitsListViewModel.kt b/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/UnitsListViewModel.kt index 377517ea..01b5a594 100644 --- a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/UnitsListViewModel.kt +++ b/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/UnitsListViewModel.kt @@ -76,18 +76,18 @@ class UnitsListViewModel @Inject constructor( } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), SecondScreenUIState()) - fun toggleFavoritesOnly(hideBrokenCurrencies: Boolean = true) { + fun toggleFavoritesOnly(hideBrokenUnits: Boolean) { viewModelScope.launch { userPrefsRepository.updateUnitConverterFavoritesOnly( !_userPrefs.value.unitConverterFavoritesOnly ) - loadUnitsToShow(hideBrokenCurrencies) + loadUnitsToShow(hideBrokenUnits) } } - fun onSearchQueryChange(newValue: String, hideBrokenCurrencies: Boolean = true) { + fun onSearchQueryChange(newValue: String, hideBrokenUnits: Boolean) { _searchQuery.update { newValue } - loadUnitsToShow(hideBrokenCurrencies) + loadUnitsToShow(hideBrokenUnits) } /** @@ -95,9 +95,9 @@ class UnitsListViewModel @Inject constructor( * * @param unit Will find group for unit with this id. */ - fun setSelectedChip(unit: String, hideBrokenCurrencies: Boolean = true) { + fun setSelectedChip(unit: String, hideBrokenUnits: Boolean) { _chosenUnitGroup.update { allUnitsRepository.getById(unit).group } - loadUnitsToShow(hideBrokenCurrencies) + loadUnitsToShow(hideBrokenUnits) } /** @@ -108,27 +108,26 @@ class UnitsListViewModel @Inject constructor( * * @param unitGroup [UnitGroup], currently selected chip. */ - fun toggleSelectedChip(unitGroup: UnitGroup, hideBrokenCurrencies: Boolean = true) { + fun toggleSelectedChip(unitGroup: UnitGroup, hideBrokenUnits: Boolean) { val newUnitGroup = if (_chosenUnitGroup.value == unitGroup) null else unitGroup _chosenUnitGroup.update { newUnitGroup } - loadUnitsToShow(hideBrokenCurrencies) + loadUnitsToShow(hideBrokenUnits) } /** * Filters and groups [AllUnitsRepository.allUnits] in coroutine * - * @param hideBrokenCurrencies Decide whether or not we are on left side. Need it because right side requires - * us to mark disabled currency units + * @param hideBrokenUnits Broken units come from currencies API (basic unit is zero) */ private fun loadUnitsToShow( - hideBrokenCurrencies: Boolean + hideBrokenUnits: Boolean ) { viewModelScope.launch { // This is mostly not UI related stuff and viewModelScope.launch uses Dispatchers.Main // So we switch to Default withContext(Dispatchers.Default) { val unitsToShow = allUnitsRepository.filterUnits( - hideBrokenCurrencies = hideBrokenCurrencies, + hideBrokenUnits = hideBrokenUnits, chosenUnitGroup = _chosenUnitGroup.value, favoritesOnly = _userPrefs.value.unitConverterFavoritesOnly, searchQuery = _searchQuery.value, diff --git a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/navigation/UnitsListNavigation.kt b/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/navigation/UnitsListNavigation.kt index 5692e92b..9c779305 100644 --- a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/navigation/UnitsListNavigation.kt +++ b/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/navigation/UnitsListNavigation.kt @@ -73,7 +73,7 @@ fun NavGraphBuilder.rightScreen( val unitFromId = it.arguments?.getString(unitFromIdArg) ?: return@composable val unitToId = it.arguments?.getString(unitToIdArg) ?: return@composable val input = it.arguments?.getString(inputArg) - viewModel.setSelectedChip(unitFromId, false) + viewModel.setSelectedChip(unitFromId, true) RightSideScreen( viewModel = viewModel,