diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/UnitsRepository.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/UnitsRepository.kt index af571078..dae97f71 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/UnitsRepository.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/UnitsRepository.kt @@ -56,11 +56,11 @@ import com.sadellie.unitto.data.units.collections.volumeCollection import com.sadellie.unitto.data.units.remote.CurrencyApi import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.update import kotlinx.coroutines.withContext import java.math.BigDecimal @@ -99,37 +99,28 @@ class UnitsRepository @Inject constructor( fuelConsumptionCollection ) - @OptIn(ExperimentalCoroutinesApi::class) - val allUnits = combine( + val allUnits: Flow> = combine( unitsDao.getAllFlow(), myUnits - ) { based, _ -> - based - } - .mapLatest { basedList -> - basedList.forEach { based -> - // Have to use a copy so that composable can detect changes - val updatedUnit = getById(based.unitId) - .clone( - isFavorite = based.isFavorite, - counter = based.frequency, - pairId = based.pairedUnitId - ) - - myUnits.update { units -> - units.replace(updatedUnit) { it.id == updatedUnit.id } - } - } - myUnits + ) { basedList, inMemoryList -> + return@combine inMemoryList.map { inMemoryUnit -> + val inBaseUnit = basedList.find { it.unitId == inMemoryUnit.id } + ?: return@map inMemoryUnit + inMemoryUnit.clone( + isFavorite = inBaseUnit.isFavorite, + counter = inBaseUnit.frequency, + pairId = inBaseUnit.pairedUnitId + ) } + } .flowOn(Dispatchers.IO) - fun getById(id: String): AbstractUnit { - return myUnits.value.first { it.id == id } + suspend fun getById(id: String): AbstractUnit { + return allUnits.first().first { it.id == id } } - fun getCollection(group: UnitGroup): List { - return myUnits.value.filter { it.group == group } + suspend fun getCollection(group: UnitGroup): List { + return allUnits.first().filter { it.group == group } } suspend fun favorite(unit: AbstractUnit) = withContext(Dispatchers.IO) { @@ -244,7 +235,7 @@ class UnitsRepository @Inject constructor( ?.let { LocalDate.ofEpochDay(it) } } - fun filterUnits( + suspend fun filterUnits( query: String, unitGroup: UnitGroup?, favoritesOnly: Boolean, @@ -254,7 +245,7 @@ class UnitsRepository @Inject constructor( ): Map> { // Leave only shown unit groups var units: Sequence = if (unitGroup == null) { - myUnits.value.filter { it.group in shownUnitGroups } + allUnits.first().filter { it.group in shownUnitGroups } } else { getCollection(unitGroup) }.asSequence() @@ -282,10 +273,4 @@ class UnitsRepository @Inject constructor( } return units.groupBy { it.group } } - - private fun List.replace(newValue: T, block: (T) -> Boolean): List { - return map { - if (block(it)) newValue else it - } - } } diff --git a/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsTest.kt b/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsTest.kt index d60d1ce4..630f51f0 100644 --- a/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsTest.kt +++ b/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsTest.kt @@ -27,6 +27,7 @@ import com.sadellie.unitto.data.model.UnitGroup import com.sadellie.unitto.data.model.unit.DefaultUnit import com.sadellie.unitto.data.model.unit.NumberBaseUnit import com.sadellie.unitto.data.model.unit.ReverseUnit +import kotlinx.coroutines.runBlocking import org.junit.After import org.junit.Assert.assertEquals import org.junit.Test @@ -541,8 +542,9 @@ class AllUnitsTest { } private fun String.checkWith(checkingId: String, value: String, expected: String) { - val unitFrom = allUnitsRepository.getById(this) - val unitTo = allUnitsRepository.getById(checkingId) + val str = this + val unitFrom = runBlocking { allUnitsRepository.getById(str) } + val unitTo = runBlocking { allUnitsRepository.getById(checkingId) } val actual = when (unitFrom.group) { UnitGroup.NUMBER_BASE -> (unitFrom as NumberBaseUnit).convert((unitTo as NumberBaseUnit), value) @@ -564,7 +566,7 @@ class AllUnitsTest { } @After - fun after() { + fun after() = runBlocking { val unitGroup = history.keys.first() // GROUP : testedCount / totalCount println("${unitGroup.name} : ${history[unitGroup]?.size} / ${allUnitsRepository.getCollection(unitGroup).size}") 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 f07cc8f1..c7d2ac13 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 @@ -52,6 +52,7 @@ import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import java.math.BigDecimal import javax.inject.Inject @@ -293,12 +294,12 @@ internal class ConverterViewModel @Inject constructor( } } - fun updateUnitFrom(unit: AbstractUnit) { + fun updateUnitFrom(unit: AbstractUnit) = viewModelScope.launch { val pair = unitsRepo.getById( unit.pairId ?: unitsRepo.getCollection(unit.group).first().id ) - viewModelScope.launch(Dispatchers.Default) { + withContext(Dispatchers.Default) { unitsRepo.incrementCounter(unit) userPrefsRepository.updateLatestPairOfUnits(unitFrom = unit, unitTo = pair) }