I have no idea what i'm doing

This commit is contained in:
Sad Ellie 2023-06-02 16:52:04 +03:00
parent f1f1b7841e
commit 4354d00652
9 changed files with 46 additions and 48 deletions

View File

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

View File

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

View File

@ -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<String, BigDecimal>
) {
suspend fun updateBasicUnitsForCurrencies(
unitFrom: AbstractUnit
) = withContext(Dispatchers.IO) {
val conversions: Map<String, BigDecimal> = 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
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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