Tiny unit converter refactor

This commit is contained in:
Sad Ellie 2023-09-11 10:36:46 +03:00
parent 2293663e9f
commit 2405a2656a
84 changed files with 2910 additions and 2990 deletions

View File

@ -123,7 +123,6 @@ dependencies {
implementation(project(mapOf("path" to ":feature:converter")))
implementation(project(mapOf("path" to ":feature:calculator")))
implementation(project(mapOf("path" to ":feature:settings")))
implementation(project(mapOf("path" to ":feature:unitslist")))
implementation(project(mapOf("path" to ":feature:datecalculator")))
implementation(project(mapOf("path" to ":feature:timezone")))
implementation(project(mapOf("path" to ":data:model")))

View File

@ -22,21 +22,14 @@ import androidx.compose.foundation.background
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import com.sadellie.unitto.feature.calculator.navigation.calculatorGraph
import com.sadellie.unitto.feature.converter.ConverterViewModel
import com.sadellie.unitto.feature.converter.navigation.converterGraph
import com.sadellie.unitto.feature.datecalculator.navigation.dateCalculatorGraph
import com.sadellie.unitto.feature.settings.navigation.navigateToSettings
import com.sadellie.unitto.feature.settings.navigation.navigateToUnitGroups
import com.sadellie.unitto.feature.settings.navigation.settingGraph
import com.sadellie.unitto.feature.unitslist.UnitsListViewModel
import com.sadellie.unitto.feature.unitslist.navigation.leftScreen
import com.sadellie.unitto.feature.unitslist.navigation.navigateToLeftSide
import com.sadellie.unitto.feature.unitslist.navigation.navigateToRightSide
import com.sadellie.unitto.feature.unitslist.navigation.rightScreen
import com.sadellie.unitto.timezone.navigation.timeZoneGraph
import io.github.sadellie.themmo.ThemmoController
@ -47,34 +40,16 @@ internal fun UnittoNavigation(
startDestination: String,
openDrawer: () -> Unit
) {
val converterViewModel: ConverterViewModel = hiltViewModel()
val unitsListViewModel: UnitsListViewModel = hiltViewModel()
NavHost(
navController = navController,
startDestination = startDestination,
modifier = Modifier.background(MaterialTheme.colorScheme.background)
) {
converterGraph(
navigateToLeftScreen = navController::navigateToLeftSide,
navigateToRightScreen = navController::navigateToRightSide,
openDrawer = openDrawer,
navController = navController,
navigateToSettings = navController::navigateToSettings,
navigateToMenu = openDrawer,
viewModel = converterViewModel
)
leftScreen(
viewModel = unitsListViewModel,
navigateUp = navController::navigateUp,
navigateToUnitGroups = navController::navigateToUnitGroups,
onSelect = converterViewModel::updateUnitFrom
)
rightScreen(
viewModel = unitsListViewModel,
navigateUp = navController::navigateUp,
navigateToUnitGroups = navController::navigateToUnitGroups,
onSelect = converterViewModel::updateUnitTo
navigateToUnitGroups = navController::navigateToUnitGroups
)
settingGraph(

View File

@ -55,13 +55,14 @@ import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.TextFieldValue
import com.sadellie.unitto.core.base.R
@Composable
fun UnittoSearchBar(
modifier: Modifier = Modifier,
query: String,
onQueryChange: (String) -> Unit,
query: TextFieldValue,
onQueryChange: (TextFieldValue) -> Unit,
navigateUp: () -> Unit,
title: String,
searchActions: @Composable (RowScope.() -> Unit) = {},
@ -78,7 +79,7 @@ fun UnittoSearchBar(
// Search text field is open, need to close it and clear search query
showSearchInput = false
// focusManager.clearFocus()
onQueryChange("")
onQueryChange(TextFieldValue())
} else {
// No search text field is shown, can go back as usual
navigateUp()
@ -116,7 +117,7 @@ fun UnittoSearchBar(
Crossfade(showSearchInput) { showSearch ->
Row(verticalAlignment = Alignment.CenterVertically) {
if (showSearch) {
ClearButton(visible = query.isNotEmpty()) { onQueryChange("") }
ClearButton(visible = query.text.isNotEmpty()) { onQueryChange(TextFieldValue()) }
searchActions()
} else {
SearchButton { showSearchInput = true }
@ -135,9 +136,9 @@ fun UnittoSearchBar(
@Composable
private fun SearchTextField(
modifier: Modifier,
value: String,
value: TextFieldValue,
placeholder: String,
onValueChange: (String) -> Unit,
onValueChange: (TextFieldValue) -> Unit,
onSearch: KeyboardActionScope.() -> Unit
) {
BasicTextField(
@ -152,7 +153,7 @@ private fun SearchTextField(
decorationBox = { innerTextField ->
innerTextField()
// Showing placeholder only when there is query is empty
value.ifEmpty {
value.text.ifEmpty {
Text(
modifier = Modifier.alpha(0.7f),
text = placeholder,

View File

@ -18,27 +18,10 @@
package com.sadellie.unitto.core.ui.common.textfield
import android.content.Context
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.core.base.Token
import java.math.BigDecimal
import java.math.RoundingMode
private val numbersRegex by lazy { Regex("[\\d.]+") }
private val timeDivisions by lazy {
mapOf(
R.string.day_short to BigDecimal("86400000000000000000000"),
R.string.hour_short to BigDecimal("3600000000000000000000"),
R.string.minute_short to BigDecimal("60000000000000000000"),
R.string.second_short to BigDecimal("1000000000000000000"),
R.string.millisecond_short to BigDecimal("1000000000000000"),
R.string.microsecond_short to BigDecimal("1000000000000"),
R.string.nanosecond_short to BigDecimal("1000000000"),
R.string.attosecond_short to BigDecimal("1"),
)
}
fun String.clearAndFilterExpression(formatterSymbols: FormatterSymbols): String {
var clean = this
.replace(formatterSymbols.grouping, "")
@ -58,51 +41,6 @@ internal fun String.clearAndFilterNumberBase(): String {
return uppercase().cleanIt(Token.numberBaseTokens)
}
/**
* Format string time conversion result into a more readable format.
*
* @param basicUnit Basic unit of the unit we convert to
* @return String like "1d 12h 12s".
*/
fun String.formatTime(
context: Context,
basicUnit: BigDecimal?,
formatterSymbols: FormatterSymbols
): String {
// We get ugly version of input (non-fancy minus)
val input = this
if (basicUnit == null) return Token.Digit._0
try {
// Don't need magic if the input is zero
if (BigDecimal(input).compareTo(BigDecimal.ZERO) == 0) return Token.Digit._0
} catch (e: NumberFormatException) {
// For case such as "10-" and "("
return Token.Digit._0
}
// Attoseconds don't need "magic"
if (basicUnit.compareTo(BigDecimal.ONE) == 0) return input.formatExpression(formatterSymbols)
var result = if (input.startsWith("-")) Token.Operator.minus else ""
var remainingSeconds = BigDecimal(input)
.abs()
.multiply(basicUnit)
.setScale(0, RoundingMode.HALF_EVEN)
if (remainingSeconds.compareTo(BigDecimal.ZERO) == 0) return Token.Digit._0
timeDivisions.forEach { (timeStr, divider) ->
val division = remainingSeconds.divideAndRemainder(divider)
val time = division.component1()
remainingSeconds = division.component2()
if (time.compareTo(BigDecimal.ZERO) != 0) {
result += "${time.toPlainString().formatExpression(formatterSymbols)}${context.getString(timeStr)} "
}
}
return result.trimEnd()
}
fun String.formatExpression(
formatterSymbols: FormatterSymbols
): String {

View File

@ -18,18 +18,14 @@
package com.sadellie.unitto.core.ui
import android.content.Context
import androidx.compose.ui.test.junit4.createComposeRule
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
import com.sadellie.unitto.core.ui.common.textfield.formatTime
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import java.math.BigDecimal
private const val ENG_VALUE = "123E+21"
private const val ENG_VALUE_FRACTIONAL = "123.3E+21"
@ -88,104 +84,4 @@ class FormatterTest {
assertEquals("50+123.456÷89.078,,9×0,812+0√9×4^9+2×(9+8×7)×sin(13sin123cos", LONG_HALF_COMPLETE_EXPR.format())
assertEquals("((((((((", SOME_BRACKETS.format())
}
@Test
fun formatTimeTest() {
val formatterSymbols = FormatterSymbols.Spaces
var basicValue = BigDecimal.valueOf(1)
val mContext: Context = RuntimeEnvironment.getApplication().applicationContext
fun String.formatTime() = this.formatTime(mContext, basicValue, formatterSymbols)
assertEquals("28", "-28".formatTime())
assertEquals("0.05", "-0.05".formatTime())
assertEquals("0", "0".formatTime())
assertEquals("0", "0".formatTime())
basicValue = BigDecimal.valueOf(86_400_000_000_000_000_000_000.0)
assertEquals("28d", "-28".formatTime())
assertEquals("1h 12m", "-0.05".formatTime())
assertEquals("0", "0".formatTime())
assertEquals("0", "-0".formatTime())
// DAYS
basicValue = BigDecimal.valueOf(86_400_000_000_000_000_000_000.0)
assertEquals("12h","0.5".formatTime())
assertEquals("1h 12m","0.05".formatTime())
assertEquals("7m 12s","0.005".formatTime())
assertEquals("28d","28".formatTime())
assertEquals("90d","90".formatTime())
assertEquals("90d 12h","90.5".formatTime())
assertEquals("90d 7m 12s","90.005".formatTime())
// HOURS
basicValue = BigDecimal.valueOf(3_600_000_000_000_000_000_000.0)
assertEquals("30m", "0.5".formatTime())
assertEquals("3m", "0.05".formatTime())
assertEquals("18s", "0.005".formatTime())
assertEquals("1d 4h", "28".formatTime())
assertEquals("3d 18h", "90".formatTime())
assertEquals("3d 18h 30m", "90.5".formatTime())
assertEquals("3d 18h 18s", "90.005".formatTime())
// MINUTES
basicValue = BigDecimal.valueOf(60_000_000_000_000_000_000.0)
assertEquals("30s", "0.5".formatTime())
assertEquals("3s", "0.05".formatTime())
assertEquals("300ms", "0.005".formatTime())
assertEquals("28m", "28".formatTime())
assertEquals("1h 30m", "90".formatTime())
assertEquals("1h 30m 30s", "90.5".formatTime())
assertEquals("1h 30m 300ms", "90.005".formatTime())
// SECONDS
basicValue = BigDecimal.valueOf(1_000_000_000_000_000_000)
assertEquals("500ms", "0.5".formatTime())
assertEquals("50ms", "0.05".formatTime())
assertEquals("5ms", "0.005".formatTime())
assertEquals("28s", "28".formatTime())
assertEquals("1m 30s", "90".formatTime())
assertEquals("1m 30s 500ms", "90.5".formatTime())
assertEquals("1m 30s 5ms", "90.005".formatTime())
// MILLISECONDS
basicValue = BigDecimal.valueOf(1_000_000_000_000_000)
assertEquals("500µs", "0.5".formatTime())
assertEquals("50µs", "0.05".formatTime())
assertEquals("5µs", "0.005".formatTime())
assertEquals("28ms", "28".formatTime())
assertEquals("90ms", "90".formatTime())
assertEquals("90ms 500µs", "90.5".formatTime())
assertEquals("90ms 5µs", "90.005".formatTime())
// MICROSECONDS
basicValue = BigDecimal.valueOf(1_000_000_000_000)
assertEquals("500ns", "0.5".formatTime())
assertEquals("50ns", "0.05".formatTime())
assertEquals("5ns", "0.005".formatTime())
assertEquals("28µs", "28".formatTime())
assertEquals("90µs", "90".formatTime())
assertEquals("90µs 500ns", "90.5".formatTime())
assertEquals("90µs 5ns", "90.005".formatTime())
// NANOSECONDS
basicValue = BigDecimal.valueOf(1_000_000_000)
assertEquals("500 000 000as", "0.5".formatTime())
assertEquals("50 000 000as", "0.05".formatTime())
assertEquals("5 000 000as", "0.005".formatTime())
assertEquals("28ns", "28".formatTime())
assertEquals("90ns", "90".formatTime())
assertEquals("90ns 500 000 000as", "90.5".formatTime())
assertEquals("90ns 5 000 000as", "90.005".formatTime())
// ATTOSECONDS
basicValue = BigDecimal.valueOf(1)
assertEquals("0.5", "0.5".formatTime())
assertEquals("0.05", "0.05".formatTime())
assertEquals("0.005", "0.005".formatTime())
assertEquals("28", "28".formatTime())
assertEquals("90", "90".formatTime())
assertEquals("90.5", "90.5".formatTime())
assertEquals("90.005", "90.005".formatTime())
}
}

View File

@ -24,6 +24,16 @@ import java.math.RoundingMode
import kotlin.math.floor
import kotlin.math.log10
fun BigDecimal.format(
scale: Int,
outputFormat: Int
): String {
return this
.setMinimumRequiredScale(scale)
.trimZeros()
.toStringWith(outputFormat)
}
/**
* Shorthand function to use correct `toString` method according to [outputFormat].
*/

View File

@ -0,0 +1,122 @@
{
"formatVersion": 1,
"database": {
"version": 4,
"identityHash": "93874ff636d0307d3643833770cf9fd2",
"entities": [
{
"tableName": "units",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`unitId` TEXT NOT NULL, `is_favorite` INTEGER NOT NULL, `paired_unit_id` TEXT, `frequency` INTEGER NOT NULL, PRIMARY KEY(`unitId`))",
"fields": [
{
"fieldPath": "unitId",
"columnName": "unitId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "isFavorite",
"columnName": "is_favorite",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "pairedUnitId",
"columnName": "paired_unit_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "frequency",
"columnName": "frequency",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"unitId"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "calculator_history",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`entityId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `expression` TEXT NOT NULL, `result` TEXT NOT NULL)",
"fields": [
{
"fieldPath": "entityId",
"columnName": "entityId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "expression",
"columnName": "expression",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "result",
"columnName": "result",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"entityId"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "time_zones",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `position` INTEGER NOT NULL, `label` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "position",
"columnName": "position",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "label",
"columnName": "label",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '93874ff636d0307d3643833770cf9fd2')"
]
}
}

View File

@ -22,12 +22,17 @@ import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import kotlinx.coroutines.flow.Flow
@Dao
interface UnitsDao {
@Query("SELECT * FROM units")
suspend fun getAll(): List<UnitsEntity>
fun getAllFlow(): Flow<List<UnitsEntity>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertUnits(vararg units: UnitsEntity)
suspend fun insertUnit(unit: UnitsEntity)
@Query("SELECT * FROM units WHERE unitId == :unitId LIMIT 1")
suspend fun getById(unitId: String): UnitsEntity?
}

View File

@ -32,7 +32,7 @@ import androidx.room.PrimaryKey
@Entity(tableName = "units")
class UnitsEntity(
@PrimaryKey val unitId: String,
@ColumnInfo(name = "is_favorite") val isFavorite: Boolean?,
@ColumnInfo(name = "paired_unit_id") val pairedUnitId: String?,
@ColumnInfo(name = "frequency") val frequency: Int? = 0,
@ColumnInfo(name = "is_favorite") val isFavorite: Boolean = false,
@ColumnInfo(name = "paired_unit_id") val pairedUnitId: String? = null,
@ColumnInfo(name = "frequency") val frequency: Int = 0,
)

View File

@ -23,7 +23,7 @@ import androidx.room.Database
import androidx.room.RoomDatabase
@Database(
version = 3,
version = 4,
exportSchema = true,
entities = [
UnitsEntity::class,
@ -33,6 +33,7 @@ import androidx.room.RoomDatabase
autoMigrations = [
AutoMigration (from = 1, to = 2),
AutoMigration (from = 2, to = 3),
AutoMigration (from = 3, to = 4),
]
)
abstract class UnittoDatabase : RoomDatabase() {

View File

@ -1,64 +0,0 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.model
import androidx.annotation.StringRes
import com.sadellie.unitto.core.base.MAX_PRECISION
import com.sadellie.unitto.data.common.setMinimumRequiredScale
import com.sadellie.unitto.data.common.trimZeros
import java.math.BigDecimal
/**
* Default representation of a unit. Uses default conversion formula.
*
* @param displayName The string resource, i.e. kilometer
* @param shortName The string resource for a short name, i.e. km
* @param basicUnit One unit of this measurement in basic unit
* @param group THe group this measurement belongs to
*/
class DefaultUnit(
unitId: String,
basicUnit: BigDecimal,
group: UnitGroup,
@StringRes displayName: Int,
@StringRes shortName: Int,
) : AbstractUnit(
unitId = unitId,
displayName = displayName,
shortName = shortName,
basicUnit = basicUnit,
group = group,
) {
override fun convert(
unitTo: AbstractUnit,
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)
.multiply(value)
.div(unitTo.basicUnit)
.setMinimumRequiredScale(scale)
.trimZeros()
}
}

View File

@ -1,6 +1,6 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2023 Elshan Agaev
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,71 +16,32 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.model
package com.sadellie.unitto.data.model.unit
import androidx.annotation.StringRes
import android.content.Context
import com.sadellie.unitto.data.common.lev
import com.sadellie.unitto.data.model.UnitGroup
import java.math.BigDecimal
/**
* This is a basic representation of what a unit must have (properties and convert function)
*
* @property unitId Unit ID from [MyUnitIDS]
* @property displayName String resource with long name, i.e. kilometer
* @property shortName String resource with short name, i.e. km
* @property basicUnit Used for conversion. Basically tells how big this unit is if comparing with
* basicUnit. For example, in [UnitGroup.LENGTH] basic unit is an attometer (1), then nanometer is
* 1.0E+9 times bigger than that. This number (1.0E+9) is a basic unit for nanometer
* @property group [UnitGroup] of this unit
* @property renderedName Used as cache. Stores long name string for this specific device. Need for
* search functionality.
* @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 pairedUnit Latest paired unit on the right
* @property counter The amount of time this unit was chosen
*/
abstract class AbstractUnit(
val unitId: String,
@StringRes val displayName: Int,
@StringRes val shortName: Int,
var basicUnit: BigDecimal,
val group: UnitGroup,
var renderedName: String = String(),
var renderedShortName: String = String(),
var isFavorite: Boolean = false,
var pairedUnit: String? = null,
var counter: Int = 0
) {
/**
* Convert this unit into another
*
* @param unitTo Unit we want to convert to (right side unit)
* @param value The amount to convert
* @param scale Which scale to use (number of decimal places)
* @return
*/
abstract fun convert(
unitTo: AbstractUnit,
value: BigDecimal,
scale: Int
): BigDecimal
interface AbstractUnit {
val id: String
val basicUnit: BigDecimal
val group: UnitGroup
val displayName: Int
val shortName: Int
val isFavorite: Boolean
val pairId: String?
val counter: Int
}
/**
* Sorts sequence of units by Levenshtein distance
*
* @param stringA String for Levenshtein distance
* @return Sorted sequence of units. Units with lower Levenshtein distance are higher
*/
fun Sequence<AbstractUnit>.sortByLev(stringA: String): Sequence<AbstractUnit> {
fun Sequence<AbstractUnit>.filterByLev(stringA: String, context: Context): Sequence<AbstractUnit> {
val stringToCompare = stringA.trim().lowercase()
// We don't need units where name is too different, half of the symbols is wrong in this situation
val threshold: Int = stringToCompare.length / 2
// List of pair: Unit and it's levDist
val unitsWithDist = mutableListOf<Pair<AbstractUnit, Int>>()
this.forEach { unit ->
val unitShortName: String = unit.renderedShortName.lowercase()
val unitShortName: String = context.getString(unit.shortName).lowercase()
/**
* There is a chance that we search for unit with a specific short name. Such cases are
* should be higher in the list. Best possible match.
@ -90,7 +51,7 @@ fun Sequence<AbstractUnit>.sortByLev(stringA: String): Sequence<AbstractUnit> {
return@forEach
}
val unitFullName: String = unit.renderedName.lowercase()
val unitFullName: String = context.getString(unit.displayName).lowercase()
/**
* There is chance that unit name doesn't need any edits (contains part of the query)

View File

@ -1,6 +1,6 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2023 Elshan Agaev
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,26 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.database
package com.sadellie.unitto.data.model.unit
import javax.inject.Inject
import java.math.BigDecimal
class UnitsRepository @Inject constructor (private val unitsDao: UnitsDao) {
/**
* Method to insert units. Will rewrite row if unit's id is already in database
*
* @param unit Unit to add
*/
suspend fun insertUnits(unit: UnitsEntity) {
unitsDao.insertUnits(unit)
}
/**
* Method to get all units from units table
*
* @return List of [UnitsEntity] objects that represent one row in table
*/
suspend fun getAll(): List<UnitsEntity> {
return unitsDao.getAll()
}
}
interface DefaultUnit : AbstractUnit {
fun convert(unitTo: DefaultUnit, value: BigDecimal): BigDecimal
}

View File

@ -0,0 +1,46 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.model.unit
import com.sadellie.unitto.core.base.MAX_PRECISION
import com.sadellie.unitto.data.model.UnitGroup
import java.math.BigDecimal
import java.math.RoundingMode
data class NormalUnit(
override val id: String,
override val basicUnit: BigDecimal,
override val group: UnitGroup,
override val displayName: Int,
override val shortName: Int,
override val isFavorite: Boolean = false,
override val pairId: String? = null,
override val counter: Int = 0,
) : DefaultUnit {
override fun convert(unitTo: DefaultUnit, value: BigDecimal): BigDecimal {
// Avoid division by zero
if (unitTo.basicUnit.compareTo(BigDecimal.ZERO) == 0) return BigDecimal.ZERO
return this
.basicUnit
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.multiply(value)
.div(unitTo.basicUnit)
}
}

View File

@ -16,28 +16,22 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.model
package com.sadellie.unitto.data.model.unit
import androidx.annotation.StringRes
import com.sadellie.unitto.data.model.UnitGroup
import java.math.BigDecimal
class NumberBaseUnit(
unitId: String,
val base: Int,
group: UnitGroup,
@StringRes displayName: Int,
@StringRes shortName: Int,
) : AbstractUnit(
unitId = unitId,
displayName = displayName,
shortName = shortName,
basicUnit = BigDecimal.ONE,
group = group,
) {
override fun convert(unitTo: AbstractUnit, value: BigDecimal, scale: Int): BigDecimal = this.basicUnit
fun convertToBase(input: String, toBase: Int): String {
return input.toBigInteger(base).toString(toBase)
data class NumberBaseUnit(
override val id: String,
override val basicUnit: BigDecimal,
override val group: UnitGroup,
override val displayName: Int,
override val shortName: Int,
override val isFavorite: Boolean = false,
override val pairId: String? = null,
override val counter: Int = 0,
) : AbstractUnit {
fun convert(toBase: NumberBaseUnit, input: String): String {
return input.toBigInteger(basicUnit.intValueExact()).toString(toBase.basicUnit.intValueExact())
}
}
}

View File

@ -16,42 +16,31 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.model
package com.sadellie.unitto.data.model.unit
import androidx.annotation.StringRes
import com.sadellie.unitto.core.base.MAX_PRECISION
import com.sadellie.unitto.data.common.setMinimumRequiredScale
import com.sadellie.unitto.data.common.trimZeros
import com.sadellie.unitto.data.model.UnitGroup
import java.math.BigDecimal
import java.math.RoundingMode
/**
* Same as [DefaultUnit], but conversion formula is different.
*
* @see DefaultUnit
*/
class FlowRateUnit(
unitId: String,
basicUnit: BigDecimal,
group: UnitGroup,
@StringRes displayName: Int,
@StringRes shortName: Int,
) : AbstractUnit(
unitId = unitId,
displayName = displayName,
shortName = shortName,
basicUnit = basicUnit,
group = group,
) {
override fun convert(
unitTo: AbstractUnit,
value: BigDecimal,
scale: Int
): BigDecimal {
return unitTo.basicUnit
.setScale(MAX_PRECISION)
data class ReverseUnit(
override val id: String,
override val basicUnit: BigDecimal,
override val group: UnitGroup,
override val displayName: Int,
override val shortName: Int,
override val isFavorite: Boolean = false,
override val pairId: String? = null,
override val counter: Int = 0,
) : DefaultUnit {
override fun convert(unitTo: DefaultUnit, value: BigDecimal): BigDecimal {
// Avoid division by zero
if (unitTo.basicUnit.compareTo(BigDecimal.ZERO) == 0) return BigDecimal.ZERO
return unitTo
.basicUnit
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.div(this.basicUnit)
.multiply(value)
.setMinimumRequiredScale(scale)
.trimZeros()
}
}

View File

@ -23,10 +23,16 @@ plugins {
android {
namespace = "com.sadellie.unitto.data.units"
testOptions.unitTests.isIncludeAndroidResources = true
}
dependencies {
testImplementation(libs.junit)
testImplementation(libs.org.robolectric)
implementation(libs.androidx.room.runtime)
implementation(libs.androidx.room.ktx)
kapt(libs.androidx.room.compiler)
implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.androidx.datastore)

View File

@ -1,221 +0,0 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.units
import android.content.Context
import com.sadellie.unitto.core.base.MAX_PRECISION
import com.sadellie.unitto.data.database.UnitsEntity
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.UnitsListSorting
import com.sadellie.unitto.data.model.sortByLev
import com.sadellie.unitto.data.units.collections.accelerationCollection
import com.sadellie.unitto.data.units.collections.angleCollection
import com.sadellie.unitto.data.units.collections.areaCollection
import com.sadellie.unitto.data.units.collections.currencyCollection
import com.sadellie.unitto.data.units.collections.dataCollection
import com.sadellie.unitto.data.units.collections.dataTransferCollection
import com.sadellie.unitto.data.units.collections.electrostaticCapacitance
import com.sadellie.unitto.data.units.collections.energyCollection
import com.sadellie.unitto.data.units.collections.flowRateCollection
import com.sadellie.unitto.data.units.collections.fluxCollection
import com.sadellie.unitto.data.units.collections.forceCollection
import com.sadellie.unitto.data.units.collections.lengthCollection
import com.sadellie.unitto.data.units.collections.luminanceCollection
import com.sadellie.unitto.data.units.collections.massCollection
import com.sadellie.unitto.data.units.collections.numberBaseCollection
import com.sadellie.unitto.data.units.collections.powerCollection
import com.sadellie.unitto.data.units.collections.prefixCollection
import com.sadellie.unitto.data.units.collections.pressureCollection
import com.sadellie.unitto.data.units.collections.speedCollection
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
/**
* This repository provides access to all collection of units in the app.
*/
@Singleton
class AllUnitsRepository @Inject constructor() {
/**
* This is a collection of all available units.
*/
private val allUnits: List<AbstractUnit> by lazy {
mapOfCollections.values.flatten()
}
/**
* Mapped [UnitGroup] to [List] of [AbstractUnit]s.
*/
private val mapOfCollections by lazy {
hashMapOf(
UnitGroup.LENGTH to lengthCollection,
UnitGroup.CURRENCY to currencyCollection,
UnitGroup.MASS to massCollection,
UnitGroup.SPEED to speedCollection,
UnitGroup.TEMPERATURE to temperatureCollection,
UnitGroup.AREA to areaCollection,
UnitGroup.TIME to timeCollection,
UnitGroup.VOLUME to volumeCollection,
UnitGroup.DATA to dataCollection,
UnitGroup.PRESSURE to pressureCollection,
UnitGroup.ACCELERATION to accelerationCollection,
UnitGroup.ENERGY to energyCollection,
UnitGroup.POWER to powerCollection,
UnitGroup.ANGLE to angleCollection,
UnitGroup.DATA_TRANSFER to dataTransferCollection,
UnitGroup.FLUX to fluxCollection,
UnitGroup.NUMBER_BASE to numberBaseCollection,
UnitGroup.ELECTROSTATIC_CAPACITANCE to electrostaticCapacitance,
UnitGroup.PREFIX to prefixCollection,
UnitGroup.FORCE to forceCollection,
UnitGroup.TORQUE to torqueCollection,
UnitGroup.FLOW_RATE to flowRateCollection,
UnitGroup.LUMINANCE to luminanceCollection,
)
}
/**
* Get [AbstractUnit] by specified id from [MyUnitIDS].
*
* @param unitId Unit id from [MyUnitIDS]. Don't use literal strings here.
* @return [AbstractUnit] from [AllUnitsRepository.allUnits] that has the given id.
* @throws NoSuchElementException If there is no [AbstractUnit] in [AllUnitsRepository.allUnits]
* that has the requested unitId.
*/
fun getById(unitId: String): AbstractUnit {
return allUnits.first { it.unitId == unitId }
}
/**
* Looks for a collection of units of the given [UnitGroup].
*
* @param unitGroup Requested [UnitGroup]
* @return List of [AbstractUnit]s. Will return null if the is no collection for the specified
* [UnitGroup].
*
* @throws [NoSuchElementException] from [Map.getValue]
*/
fun getCollectionByGroup(unitGroup: UnitGroup): List<AbstractUnit> {
return mapOfCollections.getValue(unitGroup)
}
/**
* Filter [AllUnitsRepository.allUnits] and group them.
*
* @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.
* @param searchQuery When not empty, will search by [AbstractUnit.renderedName] using [sortByLev].
* @param allUnitsGroups All [UnitGroup]s. Determines which units will be used for filtering.
* @param sorting Sorting mode from [UnitsListSorting]
*
* @return Grouped by [UnitGroup] list of [AbstractUnit]s.
*/
fun filterUnits(
hideBrokenUnits: Boolean,
chosenUnitGroup: UnitGroup?,
favoritesOnly: Boolean,
searchQuery: String,
allUnitsGroups: List<UnitGroup>,
sorting: UnitsListSorting = UnitsListSorting.USAGE
): Map<UnitGroup, List<AbstractUnit>> {
// Leave only shown unit groups
var units: Sequence<AbstractUnit> = if (chosenUnitGroup == null) {
allUnits.filter { it.group in allUnitsGroups }
} else {
val collection = getCollectionByGroup(chosenUnitGroup)
collection
}.asSequence()
if (favoritesOnly) {
units = units.filter { it.isFavorite }
}
if (hideBrokenUnits) {
units = units.filter { it.basicUnit > BigDecimal.ZERO }
}
units = when (sorting) {
UnitsListSorting.USAGE -> units.sortedByDescending { it.counter }
UnitsListSorting.ALPHABETICAL -> units.sortedBy { it.renderedName }
UnitsListSorting.SCALE_ASC -> units.sortedBy { it.basicUnit }
UnitsListSorting.SCALE_DESC -> units.sortedByDescending { it.basicUnit }
}
units = if (searchQuery.isEmpty()) {
units.sortedByDescending { it.isFavorite }
} else {
// For search we sort by popularity and Levenshtein distance (short and long name).
units.sortByLev(searchQuery)
}
return units.groupBy { it.group }
}
/**
* Maps data from database to [allUnits] item: favorites, counters, renderedNames and etc.
*
* @param context [Context] that is used to fill [AbstractUnit.renderedName]. Rendered names are used when
* searching.
* @param allUnits List from database. See: [UnitsEntity].
*/
fun loadFromDatabase(context: Context, allUnits: List<UnitsEntity>) {
this.allUnits.forEach {
// Loading unit names so that we can search through them
it.renderedName = context.getString(it.displayName)
it.renderedShortName = context.getString(it.shortName)
val fromDb = allUnits.firstOrNull { fromDb -> fromDb.unitId == it.unitId }
// Loading paired units
it.pairedUnit = fromDb?.pairedUnitId
// Loading favorite state
it.isFavorite = fromDb?.isFavorite ?: false
it.counter = fromDb?.frequency ?: 0
}
}
/**
* Update [AbstractUnit.basicUnit] properties for currencies from [currencyCollection].
*
* @param unitFrom Base unit
*/
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.basicUnit = BigDecimal.ONE.setScale(MAX_PRECISION).div(rate)
} else {
it.basicUnit = BigDecimal.ZERO
}
}
}
}

View File

@ -18,9 +18,72 @@
package com.sadellie.unitto.data.units
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.stateIn
@Suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST", "UNUSED")
fun <T1, T2, T3, T4, T5, T6, R> combine(
flow: Flow<T1>,
flow2: Flow<T2>,
flow3: Flow<T3>,
flow4: Flow<T4>,
flow5: Flow<T5>,
flow6: Flow<T6>,
transform: suspend (T1, T2, T3, T4, T5, T6) -> R,
): Flow<R> =
kotlinx.coroutines.flow.combine(
flow,
flow2,
flow3,
flow4,
flow5,
flow6,
) { 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,
)
}
@Suppress("UNCHECKED_CAST", "UNUSED")
fun <T1, T2, T3, T4, T5, T6, T7, R> combine(
flow: Flow<T1>,
flow2: Flow<T2>,
flow3: Flow<T3>,
flow4: Flow<T4>,
flow5: Flow<T5>,
flow6: Flow<T6>,
flow7: Flow<T7>,
transform: suspend (T1, T2, T3, T4, T5, T6, T7) -> R,
): Flow<R> =
kotlinx.coroutines.flow.combine(
flow,
flow2,
flow3,
flow4,
flow5,
flow6,
flow7,
) { 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,
)
}
@Suppress("UNCHECKED_CAST", "UNUSED")
fun <T1, T2, T3, T4, T5, T6, T7, T8, R> combine(
flow: Flow<T1>,
flow2: Flow<T2>,
@ -30,9 +93,18 @@ fun <T1, T2, T3, T4, T5, T6, T7, T8, R> combine(
flow6: Flow<T6>,
flow7: Flow<T7>,
flow8: Flow<T8>,
transform: suspend (T1, T2, T3, T4, T5, T6, T7, T8) -> R
transform: suspend (T1, T2, T3, T4, T5, T6, T7, T8) -> R,
): Flow<R> =
kotlinx.coroutines.flow.combine(flow, flow2, flow3, flow4, flow5, flow6, flow7, flow8) { args: Array<*> ->
kotlinx.coroutines.flow.combine(
flow,
flow2,
flow3,
flow4,
flow5,
flow6,
flow7,
flow8
) { args: Array<*> ->
transform(
args[0] as T1,
args[1] as T2,
@ -44,3 +116,6 @@ fun <T1, T2, T3, T4, T5, T6, T7, T8, R> combine(
args[7] as T8,
)
}
fun <T> Flow<T>.stateIn(scope: CoroutineScope, initialValue: T): StateFlow<T> =
stateIn(scope, SharingStarted.WhileSubscribed(5000L), initialValue)

View File

@ -0,0 +1,272 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.units
import android.content.Context
import com.sadellie.unitto.data.database.UnitsDao
import com.sadellie.unitto.data.database.UnitsEntity
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.model.unit.NumberBaseUnit
import com.sadellie.unitto.data.model.unit.ReverseUnit
import com.sadellie.unitto.data.model.unit.filterByLev
import com.sadellie.unitto.data.units.collections.accelerationCollection
import com.sadellie.unitto.data.units.collections.angleCollection
import com.sadellie.unitto.data.units.collections.areaCollection
import com.sadellie.unitto.data.units.collections.currencyCollection
import com.sadellie.unitto.data.units.collections.dataCollection
import com.sadellie.unitto.data.units.collections.dataTransferCollection
import com.sadellie.unitto.data.units.collections.electrostaticCapacitance
import com.sadellie.unitto.data.units.collections.energyCollection
import com.sadellie.unitto.data.units.collections.flowRateCollection
import com.sadellie.unitto.data.units.collections.fluxCollection
import com.sadellie.unitto.data.units.collections.forceCollection
import com.sadellie.unitto.data.units.collections.lengthCollection
import com.sadellie.unitto.data.units.collections.luminanceCollection
import com.sadellie.unitto.data.units.collections.massCollection
import com.sadellie.unitto.data.units.collections.numberBaseCollection
import com.sadellie.unitto.data.units.collections.powerCollection
import com.sadellie.unitto.data.units.collections.prefixCollection
import com.sadellie.unitto.data.units.collections.pressureCollection
import com.sadellie.unitto.data.units.collections.speedCollection
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 dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.withContext
import java.math.BigDecimal
import javax.inject.Inject
class UnitsRepository @Inject constructor(
private val unitsDao: UnitsDao,
@ApplicationContext private val mContext: Context,
) {
private val myUnits = MutableStateFlow(
lengthCollection +
currencyCollection +
massCollection +
speedCollection +
temperatureCollection +
areaCollection +
timeCollection +
volumeCollection +
dataCollection +
pressureCollection +
accelerationCollection +
energyCollection +
powerCollection +
angleCollection +
dataTransferCollection +
fluxCollection +
numberBaseCollection +
electrostaticCapacitance +
prefixCollection +
forceCollection +
torqueCollection +
flowRateCollection +
luminanceCollection
)
@OptIn(ExperimentalCoroutinesApi::class)
val allUnits = combine(
unitsDao.getAllFlow(),
myUnits
) { based, _ ->
based
}
.mapLatest { basedList ->
basedList.forEach { based ->
// Have to use a copy so that composable can detect changes
val updatedUnit = when(val foundUnit = getById(based.unitId)) {
is NormalUnit -> foundUnit.copy(
isFavorite = based.isFavorite,
counter = based.frequency,
pairId = based.pairedUnitId
)
is NumberBaseUnit -> foundUnit.copy(
isFavorite = based.isFavorite,
counter = based.frequency,
pairId = based.pairedUnitId
)
is ReverseUnit -> foundUnit.copy(
isFavorite = based.isFavorite,
counter = based.frequency,
pairId = based.pairedUnitId
)
else -> return@forEach
}
myUnits.update { units ->
units.replace(updatedUnit) { it.id == updatedUnit.id }
}
}
myUnits
}
.flowOn(Dispatchers.IO)
fun getById(id: String): AbstractUnit {
return myUnits.value.first { it.id == id }
}
fun getCollection(group: UnitGroup): List<AbstractUnit> {
return myUnits.value.filter { it.group == group }
}
suspend fun favorite(unit: AbstractUnit) = withContext(Dispatchers.IO) {
val basedUnit = unitsDao.getById(unit.id)
if (basedUnit == null) {
unitsDao.insertUnit(
UnitsEntity(
unitId = unit.id,
isFavorite = true
)
)
} else {
unitsDao.insertUnit(
UnitsEntity(
unitId = basedUnit.unitId,
isFavorite = !basedUnit.isFavorite,
pairedUnitId = basedUnit.pairedUnitId,
frequency = basedUnit.frequency
)
)
}
}
suspend fun incrementCounter(unit: AbstractUnit) = withContext(Dispatchers.IO) {
val basedUnit = unitsDao.getById(unit.id)
if (basedUnit == null) {
unitsDao.insertUnit(
UnitsEntity(
unitId = unit.id,
frequency = 1
)
)
} else {
unitsDao.insertUnit(
UnitsEntity(
unitId = basedUnit.unitId,
isFavorite = basedUnit.isFavorite,
pairedUnitId = basedUnit.pairedUnitId,
frequency = basedUnit.frequency + 1
)
)
}
}
suspend fun setPair(unit: AbstractUnit, pair: AbstractUnit) = withContext(Dispatchers.IO) {
val basedUnit = unitsDao.getById(unit.id)
if (basedUnit == null) {
unitsDao.insertUnit(
UnitsEntity(
unitId = unit.id,
pairedUnitId = pair.id
)
)
} else {
unitsDao.insertUnit(
UnitsEntity(
unitId = basedUnit.unitId,
isFavorite = basedUnit.isFavorite,
pairedUnitId = pair.id,
frequency = basedUnit.frequency
)
)
}
}
suspend fun updateRates(unit: AbstractUnit) = withContext(Dispatchers.IO) {
val conversions: Map<String, BigDecimal> = CurrencyApi.service.getCurrencyPairs(unit.id).currency
myUnits.update { item ->
item.map {
if (it.group != UnitGroup.CURRENCY) return@map it
if (it !is NormalUnit) return@map it
val rate = conversions.getOrElse(it.id) { BigDecimal.ZERO }
return@map if (rate > BigDecimal.ZERO) {
it.copy(basicUnit = rate)
} else {
it.copy(basicUnit = BigDecimal.ZERO)
}
}
}
}
fun filterUnits(
query: String,
unitGroup: UnitGroup?,
favoritesOnly: Boolean,
hideBrokenUnits: Boolean,
sorting: UnitsListSorting,
shownUnitGroups: List<UnitGroup>,
): Map<UnitGroup, List<AbstractUnit>> {
// Leave only shown unit groups
var units: Sequence<AbstractUnit> = if (unitGroup == null) {
myUnits.value.filter { it.group in shownUnitGroups }
} else {
getCollection(unitGroup)
}.asSequence()
if (favoritesOnly) {
units = units.filter { it.isFavorite }
}
if (hideBrokenUnits) {
units = units.filter { it.basicUnit > BigDecimal.ZERO }
}
units = when (sorting) {
UnitsListSorting.USAGE -> units.sortedByDescending { it.counter }
UnitsListSorting.ALPHABETICAL -> units.sortedBy { mContext.getString(it.displayName) }
UnitsListSorting.SCALE_ASC -> units.sortedBy { it.basicUnit }
UnitsListSorting.SCALE_DESC -> units.sortedByDescending { it.basicUnit }
else -> units
}
units = if (query.isEmpty()) {
units.sortedByDescending { it.isFavorite }
} else {
// For search we sort by popularity and Levenshtein distance (short and long name).
units.filterByLev(query, mContext)
}
return units.groupBy { it.group }
}
private fun <T> List<T>.replace(newValue: T, block: (T) -> Boolean): List<T> {
return map {
if (block(it)) newValue else it
}
}
}

View File

@ -19,35 +19,35 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val accelerationCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.attometer_per_square_second, BigDecimal.valueOf(1), UnitGroup.ACCELERATION, R.string.attometer_per_square_second, R.string.attometer_per_square_second_short),
DefaultUnit(MyUnitIDS.femtometer_per_square_second, BigDecimal.valueOf(1E+3), UnitGroup.ACCELERATION, R.string.femtometer_per_square_second, R.string.femtometer_per_square_second_short),
DefaultUnit(MyUnitIDS.picometer_per_square_second, BigDecimal.valueOf(1E+6), UnitGroup.ACCELERATION, R.string.picometer_per_square_second, R.string.picometer_per_square_second_short),
DefaultUnit(MyUnitIDS.nanometer_per_square_second, BigDecimal.valueOf(1E+9), UnitGroup.ACCELERATION, R.string.nanometer_per_square_second, R.string.nanometer_per_square_second_short),
DefaultUnit(MyUnitIDS.micrometer_per_square_second, BigDecimal.valueOf(1E+12), UnitGroup.ACCELERATION, R.string.micrometer_per_square_second, R.string.micrometer_per_square_second_short),
DefaultUnit(MyUnitIDS.millimeter_per_square_second, BigDecimal.valueOf(1E+15), UnitGroup.ACCELERATION, R.string.millimeter_per_square_second, R.string.millimeter_per_square_second_short),
DefaultUnit(MyUnitIDS.centimeter_per_square_second, BigDecimal.valueOf(1E+16), UnitGroup.ACCELERATION, R.string.centimeter_per_square_second, R.string.centimeter_per_square_second_short),
DefaultUnit(MyUnitIDS.decimeter_per_square_second, BigDecimal.valueOf(1E+17), UnitGroup.ACCELERATION, R.string.decimeter_per_square_second, R.string.decimeter_per_square_second_short),
DefaultUnit(MyUnitIDS.meter_per_square_second, BigDecimal.valueOf(1E+18), UnitGroup.ACCELERATION, R.string.meter_per_square_second, R.string.meter_per_square_second_short),
DefaultUnit(MyUnitIDS.kilometer_per_square_second, BigDecimal.valueOf(1E+21), UnitGroup.ACCELERATION, R.string.kilometer_per_square_second, R.string.kilometer_per_square_second_short),
DefaultUnit(MyUnitIDS.dekameter_per_square_second, BigDecimal.valueOf(1E+19), UnitGroup.ACCELERATION, R.string.dekameter_per_square_second, R.string.dekameter_per_square_second_short),
DefaultUnit(MyUnitIDS.hectometer_per_square_second, BigDecimal.valueOf(1E+20), UnitGroup.ACCELERATION, R.string.hectometer_per_square_second, R.string.hectometer_per_square_second_short),
DefaultUnit(MyUnitIDS.gal, BigDecimal.valueOf(1E+16), UnitGroup.ACCELERATION, R.string.gal, R.string.gal_short),
DefaultUnit(MyUnitIDS.mercury_surface_gravity, BigDecimal.valueOf(3.7E+18), UnitGroup.ACCELERATION, R.string.mercury_surface_gravity, R.string.mercury_surface_gravity_short),
DefaultUnit(MyUnitIDS.venus_surface_gravity, BigDecimal.valueOf(8.87E+18), UnitGroup.ACCELERATION, R.string.venus_surface_gravity, R.string.venus_surface_gravity_short),
DefaultUnit(MyUnitIDS.earth_surface_gravity, BigDecimal.valueOf(9.80655E+18), UnitGroup.ACCELERATION, R.string.earth_surface_gravity, R.string.earth_surface_gravity_short),
DefaultUnit(MyUnitIDS.mars_surface_gravity, BigDecimal.valueOf(3.71E+18), UnitGroup.ACCELERATION, R.string.mars_surface_gravity, R.string.mars_surface_gravity_short),
DefaultUnit(MyUnitIDS.jupiter_surface_gravity, BigDecimal.valueOf(2.479E+19), UnitGroup.ACCELERATION, R.string.jupiter_surface_gravity, R.string.jupiter_surface_gravity_short),
DefaultUnit(MyUnitIDS.saturn_surface_gravity, BigDecimal.valueOf(1.044E+19), UnitGroup.ACCELERATION, R.string.saturn_surface_gravity, R.string.saturn_surface_gravity_short),
DefaultUnit(MyUnitIDS.uranus_surface_gravity, BigDecimal.valueOf(8.87E+18), UnitGroup.ACCELERATION, R.string.uranus_surface_gravity, R.string.uranus_surface_gravity_short),
DefaultUnit(MyUnitIDS.neptune_surface_gravity, BigDecimal.valueOf(1.115E+19), UnitGroup.ACCELERATION, R.string.neptune_surface_gravity, R.string.neptune_surface_gravity_short),
DefaultUnit(MyUnitIDS.sun_surface_gravity, BigDecimal.valueOf(2.74E+20), UnitGroup.ACCELERATION, R.string.sun_surface_gravity, R.string.sun_surface_gravity_short),
NormalUnit(MyUnitIDS.attometer_per_square_second, BigDecimal.valueOf(1), UnitGroup.ACCELERATION, R.string.attometer_per_square_second, R.string.attometer_per_square_second_short),
NormalUnit(MyUnitIDS.femtometer_per_square_second, BigDecimal.valueOf(1E+3), UnitGroup.ACCELERATION, R.string.femtometer_per_square_second, R.string.femtometer_per_square_second_short),
NormalUnit(MyUnitIDS.picometer_per_square_second, BigDecimal.valueOf(1E+6), UnitGroup.ACCELERATION, R.string.picometer_per_square_second, R.string.picometer_per_square_second_short),
NormalUnit(MyUnitIDS.nanometer_per_square_second, BigDecimal.valueOf(1E+9), UnitGroup.ACCELERATION, R.string.nanometer_per_square_second, R.string.nanometer_per_square_second_short),
NormalUnit(MyUnitIDS.micrometer_per_square_second, BigDecimal.valueOf(1E+12), UnitGroup.ACCELERATION, R.string.micrometer_per_square_second, R.string.micrometer_per_square_second_short),
NormalUnit(MyUnitIDS.millimeter_per_square_second, BigDecimal.valueOf(1E+15), UnitGroup.ACCELERATION, R.string.millimeter_per_square_second, R.string.millimeter_per_square_second_short),
NormalUnit(MyUnitIDS.centimeter_per_square_second, BigDecimal.valueOf(1E+16), UnitGroup.ACCELERATION, R.string.centimeter_per_square_second, R.string.centimeter_per_square_second_short),
NormalUnit(MyUnitIDS.decimeter_per_square_second, BigDecimal.valueOf(1E+17), UnitGroup.ACCELERATION, R.string.decimeter_per_square_second, R.string.decimeter_per_square_second_short),
NormalUnit(MyUnitIDS.meter_per_square_second, BigDecimal.valueOf(1E+18), UnitGroup.ACCELERATION, R.string.meter_per_square_second, R.string.meter_per_square_second_short),
NormalUnit(MyUnitIDS.kilometer_per_square_second, BigDecimal.valueOf(1E+21), UnitGroup.ACCELERATION, R.string.kilometer_per_square_second, R.string.kilometer_per_square_second_short),
NormalUnit(MyUnitIDS.dekameter_per_square_second, BigDecimal.valueOf(1E+19), UnitGroup.ACCELERATION, R.string.dekameter_per_square_second, R.string.dekameter_per_square_second_short),
NormalUnit(MyUnitIDS.hectometer_per_square_second, BigDecimal.valueOf(1E+20), UnitGroup.ACCELERATION, R.string.hectometer_per_square_second, R.string.hectometer_per_square_second_short),
NormalUnit(MyUnitIDS.gal, BigDecimal.valueOf(1E+16), UnitGroup.ACCELERATION, R.string.gal, R.string.gal_short),
NormalUnit(MyUnitIDS.mercury_surface_gravity, BigDecimal.valueOf(3.7E+18), UnitGroup.ACCELERATION, R.string.mercury_surface_gravity, R.string.mercury_surface_gravity_short),
NormalUnit(MyUnitIDS.venus_surface_gravity, BigDecimal.valueOf(8.87E+18), UnitGroup.ACCELERATION, R.string.venus_surface_gravity, R.string.venus_surface_gravity_short),
NormalUnit(MyUnitIDS.earth_surface_gravity, BigDecimal.valueOf(9.80655E+18), UnitGroup.ACCELERATION, R.string.earth_surface_gravity, R.string.earth_surface_gravity_short),
NormalUnit(MyUnitIDS.mars_surface_gravity, BigDecimal.valueOf(3.71E+18), UnitGroup.ACCELERATION, R.string.mars_surface_gravity, R.string.mars_surface_gravity_short),
NormalUnit(MyUnitIDS.jupiter_surface_gravity, BigDecimal.valueOf(2.479E+19), UnitGroup.ACCELERATION, R.string.jupiter_surface_gravity, R.string.jupiter_surface_gravity_short),
NormalUnit(MyUnitIDS.saturn_surface_gravity, BigDecimal.valueOf(1.044E+19), UnitGroup.ACCELERATION, R.string.saturn_surface_gravity, R.string.saturn_surface_gravity_short),
NormalUnit(MyUnitIDS.uranus_surface_gravity, BigDecimal.valueOf(8.87E+18), UnitGroup.ACCELERATION, R.string.uranus_surface_gravity, R.string.uranus_surface_gravity_short),
NormalUnit(MyUnitIDS.neptune_surface_gravity, BigDecimal.valueOf(1.115E+19), UnitGroup.ACCELERATION, R.string.neptune_surface_gravity, R.string.neptune_surface_gravity_short),
NormalUnit(MyUnitIDS.sun_surface_gravity, BigDecimal.valueOf(2.74E+20), UnitGroup.ACCELERATION, R.string.sun_surface_gravity, R.string.sun_surface_gravity_short),
)
}
}

View File

@ -19,19 +19,19 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val angleCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.angle_second, BigDecimal.valueOf(1), UnitGroup.ANGLE, R.string.angle_second, R.string.angle_second_short),
DefaultUnit(MyUnitIDS.angle_minute, BigDecimal.valueOf(60), UnitGroup.ANGLE, R.string.angle_minute, R.string.angle_minute_short),
DefaultUnit(MyUnitIDS.degree, BigDecimal.valueOf(3600), UnitGroup.ANGLE, R.string.degree, R.string.degree_short),
DefaultUnit(MyUnitIDS.radian, BigDecimal.valueOf(206264.8062471), UnitGroup.ANGLE, R.string.radian, R.string.radian_short),
DefaultUnit(MyUnitIDS.sextant, BigDecimal.valueOf(216000), UnitGroup.ANGLE, R.string.sextant, R.string.sextant_short),
DefaultUnit(MyUnitIDS.turn, BigDecimal.valueOf(1296000), UnitGroup.ANGLE, R.string.turn, R.string.turn_short),
NormalUnit(MyUnitIDS.angle_second, BigDecimal.valueOf(1), UnitGroup.ANGLE, R.string.angle_second, R.string.angle_second_short),
NormalUnit(MyUnitIDS.angle_minute, BigDecimal.valueOf(60), UnitGroup.ANGLE, R.string.angle_minute, R.string.angle_minute_short),
NormalUnit(MyUnitIDS.degree, BigDecimal.valueOf(3600), UnitGroup.ANGLE, R.string.degree, R.string.degree_short),
NormalUnit(MyUnitIDS.radian, BigDecimal.valueOf(206264.8062471), UnitGroup.ANGLE, R.string.radian, R.string.radian_short),
NormalUnit(MyUnitIDS.sextant, BigDecimal.valueOf(216000), UnitGroup.ANGLE, R.string.sextant, R.string.sextant_short),
NormalUnit(MyUnitIDS.turn, BigDecimal.valueOf(1296000), UnitGroup.ANGLE, R.string.turn, R.string.turn_short),
)
}
}

View File

@ -19,27 +19,27 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val areaCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.cent, BigDecimal.valueOf(6.083246572E+33), UnitGroup.AREA, R.string.cent, R.string.cent_short),
DefaultUnit(MyUnitIDS.acre, BigDecimal.valueOf(6.083246572E+31), UnitGroup.AREA, R.string.acre, R.string.acre_short),
DefaultUnit(MyUnitIDS.hectare, BigDecimal.valueOf(1.503202964E+32), UnitGroup.AREA, R.string.hectare, R.string.hectare_short ),
DefaultUnit(MyUnitIDS.square_foot, BigDecimal.valueOf(1.396521251E+27), UnitGroup.AREA, R.string.square_foot, R.string.square_foot_short),
DefaultUnit(MyUnitIDS.square_mile, BigDecimal.valueOf(3.893277806E+34), UnitGroup.AREA, R.string.square_mile, R.string.square_mile_short),
DefaultUnit(MyUnitIDS.square_yard, BigDecimal.valueOf(1.256869126E+28), UnitGroup.AREA, R.string.square_yard, R.string.square_yard_short),
DefaultUnit(MyUnitIDS.square_inch, BigDecimal.valueOf(9.698064247E+24), UnitGroup.AREA, R.string.square_inch, R.string.square_inch_short),
DefaultUnit(MyUnitIDS.square_micrometer, BigDecimal.valueOf(1.503202964E+16), UnitGroup.AREA, R.string.square_micrometer, R.string.square_micrometer_short),
DefaultUnit(MyUnitIDS.square_millimeter, BigDecimal.valueOf(1.503202964E+22), UnitGroup.AREA, R.string.square_millimeter, R.string.square_millimeter_short),
DefaultUnit(MyUnitIDS.square_centimeter, BigDecimal.valueOf(1.503202964E+24), UnitGroup.AREA, R.string.square_centimeter, R.string.square_centimeter_short),
DefaultUnit(MyUnitIDS.square_decimeter, BigDecimal.valueOf(1.503202964E+26), UnitGroup.AREA, R.string.square_decimeter, R.string.square_decimeter_short),
DefaultUnit(MyUnitIDS.square_meter, BigDecimal.valueOf(1.503202964E+28), UnitGroup.AREA, R.string.square_meter, R.string.square_meter_short),
DefaultUnit(MyUnitIDS.square_kilometer, BigDecimal.valueOf(1.503202964E+34), UnitGroup.AREA, R.string.square_kilometer, R.string.square_kilometer_short),
DefaultUnit(MyUnitIDS.electron_cross_section, BigDecimal.valueOf(1.0), UnitGroup.AREA, R.string.electron_cross_section, R.string.electron_cross_section_short),
NormalUnit(MyUnitIDS.cent, BigDecimal.valueOf(6.083246572E+33), UnitGroup.AREA, R.string.cent, R.string.cent_short),
NormalUnit(MyUnitIDS.acre, BigDecimal.valueOf(6.083246572E+31), UnitGroup.AREA, R.string.acre, R.string.acre_short),
NormalUnit(MyUnitIDS.hectare, BigDecimal.valueOf(1.503202964E+32), UnitGroup.AREA, R.string.hectare, R.string.hectare_short ),
NormalUnit(MyUnitIDS.square_foot, BigDecimal.valueOf(1.396521251E+27), UnitGroup.AREA, R.string.square_foot, R.string.square_foot_short),
NormalUnit(MyUnitIDS.square_mile, BigDecimal.valueOf(3.893277806E+34), UnitGroup.AREA, R.string.square_mile, R.string.square_mile_short),
NormalUnit(MyUnitIDS.square_yard, BigDecimal.valueOf(1.256869126E+28), UnitGroup.AREA, R.string.square_yard, R.string.square_yard_short),
NormalUnit(MyUnitIDS.square_inch, BigDecimal.valueOf(9.698064247E+24), UnitGroup.AREA, R.string.square_inch, R.string.square_inch_short),
NormalUnit(MyUnitIDS.square_micrometer, BigDecimal.valueOf(1.503202964E+16), UnitGroup.AREA, R.string.square_micrometer, R.string.square_micrometer_short),
NormalUnit(MyUnitIDS.square_millimeter, BigDecimal.valueOf(1.503202964E+22), UnitGroup.AREA, R.string.square_millimeter, R.string.square_millimeter_short),
NormalUnit(MyUnitIDS.square_centimeter, BigDecimal.valueOf(1.503202964E+24), UnitGroup.AREA, R.string.square_centimeter, R.string.square_centimeter_short),
NormalUnit(MyUnitIDS.square_decimeter, BigDecimal.valueOf(1.503202964E+26), UnitGroup.AREA, R.string.square_decimeter, R.string.square_decimeter_short),
NormalUnit(MyUnitIDS.square_meter, BigDecimal.valueOf(1.503202964E+28), UnitGroup.AREA, R.string.square_meter, R.string.square_meter_short),
NormalUnit(MyUnitIDS.square_kilometer, BigDecimal.valueOf(1.503202964E+34), UnitGroup.AREA, R.string.square_kilometer, R.string.square_kilometer_short),
NormalUnit(MyUnitIDS.electron_cross_section, BigDecimal.valueOf(1.0), UnitGroup.AREA, R.string.electron_cross_section, R.string.electron_cross_section_short),
)
}
}

View File

@ -1,43 +0,0 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val electrostaticCapacitance: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.attofarad, BigDecimal.valueOf(1), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.attofarad, R.string.attofarad_short),
DefaultUnit(MyUnitIDS.picofarad, BigDecimal.valueOf(1E+6), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.picofarad, R.string.picofarad_short),
DefaultUnit(MyUnitIDS.statfarad, BigDecimal.valueOf(1112650.0561), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.statfarad, R.string.statfarad_short),
DefaultUnit(MyUnitIDS.nanofarad, BigDecimal.valueOf(1E+9), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.nanofarad, R.string.nanofarad_short),
DefaultUnit(MyUnitIDS.microfarad, BigDecimal.valueOf(1E+12), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.microfarad, R.string.microfarad_short),
DefaultUnit(MyUnitIDS.millifarad, BigDecimal.valueOf(1E+15), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.millifarad, R.string.millifarad_short),
DefaultUnit(MyUnitIDS.farad, BigDecimal.valueOf(1E+18), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.farad, R.string.farad_short),
DefaultUnit(MyUnitIDS.kilofarad, BigDecimal.valueOf(1E+21), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.kilofarad, R.string.kilofarad_short),
DefaultUnit(MyUnitIDS.megafarad, BigDecimal.valueOf(1E+24), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.megafarad, R.string.megafarad_short),
DefaultUnit(MyUnitIDS.gigafarad, BigDecimal.valueOf(1E+27), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.gigafarad, R.string.gigafarad_short),
DefaultUnit(MyUnitIDS.petafarad, BigDecimal.valueOf(1E+33), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.petafarad, R.string.petafarad_short),
DefaultUnit(MyUnitIDS.exafarad, BigDecimal.valueOf(1E+36), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.exafarad, R.string.exafarad_short),
)
}

View File

@ -19,221 +19,221 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val currencyCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.currency_1inch, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_1inch, R.string.currency_1inch_short),
DefaultUnit(MyUnitIDS.currency_ada, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ada, R.string.currency_ada_short),
DefaultUnit(MyUnitIDS.currency_aed, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_aed, R.string.currency_aed_short),
DefaultUnit(MyUnitIDS.currency_afn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_afn, R.string.currency_afn_short),
DefaultUnit(MyUnitIDS.currency_algo, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_algo, R.string.currency_algo_short),
DefaultUnit(MyUnitIDS.currency_all, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_all, R.string.currency_all_short),
DefaultUnit(MyUnitIDS.currency_amd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_amd, R.string.currency_amd_short),
DefaultUnit(MyUnitIDS.currency_ang, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ang, R.string.currency_ang_short),
DefaultUnit(MyUnitIDS.currency_aoa, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_aoa, R.string.currency_aoa_short),
DefaultUnit(MyUnitIDS.currency_ars, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ars, R.string.currency_ars_short),
DefaultUnit(MyUnitIDS.currency_atom, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_atom, R.string.currency_atom_short),
DefaultUnit(MyUnitIDS.currency_aud, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_aud, R.string.currency_aud_short),
DefaultUnit(MyUnitIDS.currency_avax, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_avax, R.string.currency_avax_short),
DefaultUnit(MyUnitIDS.currency_awg, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_awg, R.string.currency_awg_short),
DefaultUnit(MyUnitIDS.currency_azn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_azn, R.string.currency_azn_short),
DefaultUnit(MyUnitIDS.currency_bam, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bam, R.string.currency_bam_short),
DefaultUnit(MyUnitIDS.currency_bbd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bbd, R.string.currency_bbd_short),
DefaultUnit(MyUnitIDS.currency_bch, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bch, R.string.currency_bch_short),
DefaultUnit(MyUnitIDS.currency_bdt, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bdt, R.string.currency_bdt_short),
DefaultUnit(MyUnitIDS.currency_bgn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bgn, R.string.currency_bgn_short),
DefaultUnit(MyUnitIDS.currency_bhd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bhd, R.string.currency_bhd_short),
DefaultUnit(MyUnitIDS.currency_bif, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bif, R.string.currency_bif_short),
DefaultUnit(MyUnitIDS.currency_bmd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bmd, R.string.currency_bmd_short),
DefaultUnit(MyUnitIDS.currency_bnb, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bnb, R.string.currency_bnb_short),
DefaultUnit(MyUnitIDS.currency_bnd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bnd, R.string.currency_bnd_short),
DefaultUnit(MyUnitIDS.currency_bob, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bob, R.string.currency_bob_short),
DefaultUnit(MyUnitIDS.currency_brl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_brl, R.string.currency_brl_short),
DefaultUnit(MyUnitIDS.currency_bsd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bsd, R.string.currency_bsd_short),
DefaultUnit(MyUnitIDS.currency_btc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_btc, R.string.currency_btc_short),
DefaultUnit(MyUnitIDS.currency_btn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_btn, R.string.currency_btn_short),
DefaultUnit(MyUnitIDS.currency_busd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_busd, R.string.currency_busd_short),
DefaultUnit(MyUnitIDS.currency_bwp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bwp, R.string.currency_bwp_short),
DefaultUnit(MyUnitIDS.currency_byn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_byn, R.string.currency_byn_short),
DefaultUnit(MyUnitIDS.currency_byr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_byr, R.string.currency_byr_short),
DefaultUnit(MyUnitIDS.currency_bzd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bzd, R.string.currency_bzd_short),
DefaultUnit(MyUnitIDS.currency_cad, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cad, R.string.currency_cad_short),
DefaultUnit(MyUnitIDS.currency_cdf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cdf, R.string.currency_cdf_short),
DefaultUnit(MyUnitIDS.currency_chf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_chf, R.string.currency_chf_short),
DefaultUnit(MyUnitIDS.currency_chz, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_chz, R.string.currency_chz_short),
DefaultUnit(MyUnitIDS.currency_clf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_clf, R.string.currency_clf_short),
DefaultUnit(MyUnitIDS.currency_clp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_clp, R.string.currency_clp_short),
DefaultUnit(MyUnitIDS.currency_cny, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cny, R.string.currency_cny_short),
DefaultUnit(MyUnitIDS.currency_cop, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cop, R.string.currency_cop_short),
DefaultUnit(MyUnitIDS.currency_crc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_crc, R.string.currency_crc_short),
DefaultUnit(MyUnitIDS.currency_cro, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cro, R.string.currency_cro_short),
DefaultUnit(MyUnitIDS.currency_cuc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cuc, R.string.currency_cuc_short),
DefaultUnit(MyUnitIDS.currency_cup, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cup, R.string.currency_cup_short),
DefaultUnit(MyUnitIDS.currency_cve, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cve, R.string.currency_cve_short),
DefaultUnit(MyUnitIDS.currency_czk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_czk, R.string.currency_czk_short),
DefaultUnit(MyUnitIDS.currency_dai, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_dai, R.string.currency_dai_short),
DefaultUnit(MyUnitIDS.currency_djf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_djf, R.string.currency_djf_short),
DefaultUnit(MyUnitIDS.currency_dkk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_dkk, R.string.currency_dkk_short),
DefaultUnit(MyUnitIDS.currency_doge, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_doge, R.string.currency_doge_short),
DefaultUnit(MyUnitIDS.currency_dop, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_dop, R.string.currency_dop_short),
DefaultUnit(MyUnitIDS.currency_dot, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_dot, R.string.currency_dot_short),
DefaultUnit(MyUnitIDS.currency_dzd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_dzd, R.string.currency_dzd_short),
DefaultUnit(MyUnitIDS.currency_egld, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_egld, R.string.currency_egld_short),
DefaultUnit(MyUnitIDS.currency_egp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_egp, R.string.currency_egp_short),
DefaultUnit(MyUnitIDS.currency_enj, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_enj, R.string.currency_enj_short),
DefaultUnit(MyUnitIDS.currency_ern, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ern, R.string.currency_ern_short),
DefaultUnit(MyUnitIDS.currency_etb, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_etb, R.string.currency_etb_short),
DefaultUnit(MyUnitIDS.currency_etc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_etc, R.string.currency_etc_short),
DefaultUnit(MyUnitIDS.currency_eth, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_eth, R.string.currency_eth_short),
DefaultUnit(MyUnitIDS.currency_eur, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_eur, R.string.currency_eur_short),
DefaultUnit(MyUnitIDS.currency_fil, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_fil, R.string.currency_fil_short),
DefaultUnit(MyUnitIDS.currency_fjd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_fjd, R.string.currency_fjd_short),
DefaultUnit(MyUnitIDS.currency_fkp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_fkp, R.string.currency_fkp_short),
DefaultUnit(MyUnitIDS.currency_ftt, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ftt, R.string.currency_ftt_short),
DefaultUnit(MyUnitIDS.currency_gbp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_gbp, R.string.currency_gbp_short),
DefaultUnit(MyUnitIDS.currency_gel, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_gel, R.string.currency_gel_short),
DefaultUnit(MyUnitIDS.currency_ggp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ggp, R.string.currency_ggp_short),
DefaultUnit(MyUnitIDS.currency_ghs, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ghs, R.string.currency_ghs_short),
DefaultUnit(MyUnitIDS.currency_gip, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_gip, R.string.currency_gip_short),
DefaultUnit(MyUnitIDS.currency_gmd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_gmd, R.string.currency_gmd_short),
DefaultUnit(MyUnitIDS.currency_gnf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_gnf, R.string.currency_gnf_short),
DefaultUnit(MyUnitIDS.currency_grt, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_grt, R.string.currency_grt_short),
DefaultUnit(MyUnitIDS.currency_gtq, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_gtq, R.string.currency_gtq_short),
DefaultUnit(MyUnitIDS.currency_gyd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_gyd, R.string.currency_gyd_short),
DefaultUnit(MyUnitIDS.currency_hkd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_hkd, R.string.currency_hkd_short),
DefaultUnit(MyUnitIDS.currency_hnl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_hnl, R.string.currency_hnl_short),
DefaultUnit(MyUnitIDS.currency_hrk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_hrk, R.string.currency_hrk_short),
DefaultUnit(MyUnitIDS.currency_htg, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_htg, R.string.currency_htg_short),
DefaultUnit(MyUnitIDS.currency_huf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_huf, R.string.currency_huf_short),
DefaultUnit(MyUnitIDS.currency_icp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_icp, R.string.currency_icp_short),
DefaultUnit(MyUnitIDS.currency_idr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_idr, R.string.currency_idr_short),
DefaultUnit(MyUnitIDS.currency_ils, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ils, R.string.currency_ils_short),
DefaultUnit(MyUnitIDS.currency_imp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_imp, R.string.currency_imp_short),
DefaultUnit(MyUnitIDS.currency_inj, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_inj, R.string.currency_inj_short),
DefaultUnit(MyUnitIDS.currency_inr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_inr, R.string.currency_inr_short),
DefaultUnit(MyUnitIDS.currency_iqd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_iqd, R.string.currency_iqd_short),
DefaultUnit(MyUnitIDS.currency_irr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_irr, R.string.currency_irr_short),
DefaultUnit(MyUnitIDS.currency_isk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_isk, R.string.currency_isk_short),
DefaultUnit(MyUnitIDS.currency_jep, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_jep, R.string.currency_jep_short),
DefaultUnit(MyUnitIDS.currency_jmd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_jmd, R.string.currency_jmd_short),
DefaultUnit(MyUnitIDS.currency_jod, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_jod, R.string.currency_jod_short),
DefaultUnit(MyUnitIDS.currency_jpy, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_jpy, R.string.currency_jpy_short),
DefaultUnit(MyUnitIDS.currency_kes, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_kes, R.string.currency_kes_short),
DefaultUnit(MyUnitIDS.currency_kgs, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_kgs, R.string.currency_kgs_short),
DefaultUnit(MyUnitIDS.currency_khr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_khr, R.string.currency_khr_short),
DefaultUnit(MyUnitIDS.currency_kmf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_kmf, R.string.currency_kmf_short),
DefaultUnit(MyUnitIDS.currency_kpw, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_kpw, R.string.currency_kpw_short),
DefaultUnit(MyUnitIDS.currency_krw, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_krw, R.string.currency_krw_short),
DefaultUnit(MyUnitIDS.currency_ksm, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ksm, R.string.currency_ksm_short),
DefaultUnit(MyUnitIDS.currency_kwd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_kwd, R.string.currency_kwd_short),
DefaultUnit(MyUnitIDS.currency_kyd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_kyd, R.string.currency_kyd_short),
DefaultUnit(MyUnitIDS.currency_kzt, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_kzt, R.string.currency_kzt_short),
DefaultUnit(MyUnitIDS.currency_lak, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_lak, R.string.currency_lak_short),
DefaultUnit(MyUnitIDS.currency_lbp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_lbp, R.string.currency_lbp_short),
DefaultUnit(MyUnitIDS.currency_link, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_link, R.string.currency_link_short),
DefaultUnit(MyUnitIDS.currency_lkr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_lkr, R.string.currency_lkr_short),
DefaultUnit(MyUnitIDS.currency_lrd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_lrd, R.string.currency_lrd_short),
DefaultUnit(MyUnitIDS.currency_lsl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_lsl, R.string.currency_lsl_short),
DefaultUnit(MyUnitIDS.currency_ltc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ltc, R.string.currency_ltc_short),
DefaultUnit(MyUnitIDS.currency_ltl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ltl, R.string.currency_ltl_short),
DefaultUnit(MyUnitIDS.currency_luna, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_luna, R.string.currency_luna_short),
DefaultUnit(MyUnitIDS.currency_lvl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_lvl, R.string.currency_lvl_short),
DefaultUnit(MyUnitIDS.currency_lyd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_lyd, R.string.currency_lyd_short),
DefaultUnit(MyUnitIDS.currency_mad, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mad, R.string.currency_mad_short),
DefaultUnit(MyUnitIDS.currency_matic, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_matic, R.string.currency_matic_short),
DefaultUnit(MyUnitIDS.currency_mdl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mdl, R.string.currency_mdl_short),
DefaultUnit(MyUnitIDS.currency_mga, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mga, R.string.currency_mga_short),
DefaultUnit(MyUnitIDS.currency_mkd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mkd, R.string.currency_mkd_short),
DefaultUnit(MyUnitIDS.currency_mmk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mmk, R.string.currency_mmk_short),
DefaultUnit(MyUnitIDS.currency_mnt, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mnt, R.string.currency_mnt_short),
DefaultUnit(MyUnitIDS.currency_mop, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mop, R.string.currency_mop_short),
DefaultUnit(MyUnitIDS.currency_mro, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mro, R.string.currency_mro_short),
DefaultUnit(MyUnitIDS.currency_mur, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mur, R.string.currency_mur_short),
DefaultUnit(MyUnitIDS.currency_mvr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mvr, R.string.currency_mvr_short),
DefaultUnit(MyUnitIDS.currency_mwk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mwk, R.string.currency_mwk_short),
DefaultUnit(MyUnitIDS.currency_mxn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mxn, R.string.currency_mxn_short),
DefaultUnit(MyUnitIDS.currency_myr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_myr, R.string.currency_myr_short),
DefaultUnit(MyUnitIDS.currency_mzn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mzn, R.string.currency_mzn_short),
DefaultUnit(MyUnitIDS.currency_nad, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_nad, R.string.currency_nad_short),
DefaultUnit(MyUnitIDS.currency_ngn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ngn, R.string.currency_ngn_short),
DefaultUnit(MyUnitIDS.currency_nio, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_nio, R.string.currency_nio_short),
DefaultUnit(MyUnitIDS.currency_nok, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_nok, R.string.currency_nok_short),
DefaultUnit(MyUnitIDS.currency_npr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_npr, R.string.currency_npr_short),
DefaultUnit(MyUnitIDS.currency_nzd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_nzd, R.string.currency_nzd_short),
DefaultUnit(MyUnitIDS.currency_omr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_omr, R.string.currency_omr_short),
DefaultUnit(MyUnitIDS.currency_one, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_one, R.string.currency_one_short),
DefaultUnit(MyUnitIDS.currency_pab, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_pab, R.string.currency_pab_short),
DefaultUnit(MyUnitIDS.currency_pen, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_pen, R.string.currency_pen_short),
DefaultUnit(MyUnitIDS.currency_pgk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_pgk, R.string.currency_pgk_short),
DefaultUnit(MyUnitIDS.currency_php, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_php, R.string.currency_php_short),
DefaultUnit(MyUnitIDS.currency_pkr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_pkr, R.string.currency_pkr_short),
DefaultUnit(MyUnitIDS.currency_pln, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_pln, R.string.currency_pln_short),
DefaultUnit(MyUnitIDS.currency_pyg, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_pyg, R.string.currency_pyg_short),
DefaultUnit(MyUnitIDS.currency_qar, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_qar, R.string.currency_qar_short),
DefaultUnit(MyUnitIDS.currency_ron, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ron, R.string.currency_ron_short),
DefaultUnit(MyUnitIDS.currency_rsd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_rsd, R.string.currency_rsd_short),
DefaultUnit(MyUnitIDS.currency_rub, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_rub, R.string.currency_rub_short),
DefaultUnit(MyUnitIDS.currency_rwf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_rwf, R.string.currency_rwf_short),
DefaultUnit(MyUnitIDS.currency_sar, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sar, R.string.currency_sar_short),
DefaultUnit(MyUnitIDS.currency_sbd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sbd, R.string.currency_sbd_short),
DefaultUnit(MyUnitIDS.currency_scr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_scr, R.string.currency_scr_short),
DefaultUnit(MyUnitIDS.currency_sdg, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sdg, R.string.currency_sdg_short),
DefaultUnit(MyUnitIDS.currency_sek, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sek, R.string.currency_sek_short),
DefaultUnit(MyUnitIDS.currency_sgd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sgd, R.string.currency_sgd_short),
DefaultUnit(MyUnitIDS.currency_shib, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_shib, R.string.currency_shib_short),
DefaultUnit(MyUnitIDS.currency_shp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_shp, R.string.currency_shp_short),
DefaultUnit(MyUnitIDS.currency_sll, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sll, R.string.currency_sll_short),
DefaultUnit(MyUnitIDS.currency_sol, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sol, R.string.currency_sol_short),
DefaultUnit(MyUnitIDS.currency_sos, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sos, R.string.currency_sos_short),
DefaultUnit(MyUnitIDS.currency_srd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_srd, R.string.currency_srd_short),
DefaultUnit(MyUnitIDS.currency_std, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_std, R.string.currency_std_short),
DefaultUnit(MyUnitIDS.currency_svc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_svc, R.string.currency_svc_short),
DefaultUnit(MyUnitIDS.currency_syp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_syp, R.string.currency_syp_short),
DefaultUnit(MyUnitIDS.currency_szl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_szl, R.string.currency_szl_short),
DefaultUnit(MyUnitIDS.currency_thb, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_thb, R.string.currency_thb_short),
DefaultUnit(MyUnitIDS.currency_theta, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_theta, R.string.currency_theta_short),
DefaultUnit(MyUnitIDS.currency_tjs, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_tjs, R.string.currency_tjs_short),
DefaultUnit(MyUnitIDS.currency_tmt, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_tmt, R.string.currency_tmt_short),
DefaultUnit(MyUnitIDS.currency_tnd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_tnd, R.string.currency_tnd_short),
DefaultUnit(MyUnitIDS.currency_top, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_top, R.string.currency_top_short),
DefaultUnit(MyUnitIDS.currency_trx, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_trx, R.string.currency_trx_short),
DefaultUnit(MyUnitIDS.currency_try, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_try, R.string.currency_try_short),
DefaultUnit(MyUnitIDS.currency_ttd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ttd, R.string.currency_ttd_short),
DefaultUnit(MyUnitIDS.currency_twd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_twd, R.string.currency_twd_short),
DefaultUnit(MyUnitIDS.currency_tzs, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_tzs, R.string.currency_tzs_short),
DefaultUnit(MyUnitIDS.currency_uah, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_uah, R.string.currency_uah_short),
DefaultUnit(MyUnitIDS.currency_ugx, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ugx, R.string.currency_ugx_short),
DefaultUnit(MyUnitIDS.currency_uni, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_uni, R.string.currency_uni_short),
DefaultUnit(MyUnitIDS.currency_usd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_usd, R.string.currency_usd_short),
DefaultUnit(MyUnitIDS.currency_usdc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_usdc, R.string.currency_usdc_short),
DefaultUnit(MyUnitIDS.currency_usdt, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_usdt, R.string.currency_usdt_short),
DefaultUnit(MyUnitIDS.currency_uyu, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_uyu, R.string.currency_uyu_short),
DefaultUnit(MyUnitIDS.currency_uzs, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_uzs, R.string.currency_uzs_short),
DefaultUnit(MyUnitIDS.currency_vef, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_vef, R.string.currency_vef_short),
DefaultUnit(MyUnitIDS.currency_vet, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_vet, R.string.currency_vet_short),
DefaultUnit(MyUnitIDS.currency_vnd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_vnd, R.string.currency_vnd_short),
DefaultUnit(MyUnitIDS.currency_vuv, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_vuv, R.string.currency_vuv_short),
DefaultUnit(MyUnitIDS.currency_wbtc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_wbtc, R.string.currency_wbtc_short),
DefaultUnit(MyUnitIDS.currency_wst, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_wst, R.string.currency_wst_short),
DefaultUnit(MyUnitIDS.currency_xaf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xaf, R.string.currency_xaf_short),
DefaultUnit(MyUnitIDS.currency_xag, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xag, R.string.currency_xag_short),
DefaultUnit(MyUnitIDS.currency_xau, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xau, R.string.currency_xau_short),
DefaultUnit(MyUnitIDS.currency_xcd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xcd, R.string.currency_xcd_short),
DefaultUnit(MyUnitIDS.currency_xdr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xdr, R.string.currency_xdr_short),
DefaultUnit(MyUnitIDS.currency_xlm, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xlm, R.string.currency_xlm_short),
DefaultUnit(MyUnitIDS.currency_xmr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xmr, R.string.currency_xmr_short),
DefaultUnit(MyUnitIDS.currency_xof, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xof, R.string.currency_xof_short),
DefaultUnit(MyUnitIDS.currency_xpf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xpf, R.string.currency_xpf_short),
DefaultUnit(MyUnitIDS.currency_xrp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xrp, R.string.currency_xrp_short),
DefaultUnit(MyUnitIDS.currency_yer, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_yer, R.string.currency_yer_short),
DefaultUnit(MyUnitIDS.currency_zar, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_zar, R.string.currency_zar_short),
DefaultUnit(MyUnitIDS.currency_zmk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_zmk, R.string.currency_zmk_short),
DefaultUnit(MyUnitIDS.currency_zmw, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_zmw, R.string.currency_zmw_short),
DefaultUnit(MyUnitIDS.currency_zwl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_zwl, R.string.currency_zwl_short),
NormalUnit(MyUnitIDS.currency_1inch, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_1inch, R.string.currency_1inch_short),
NormalUnit(MyUnitIDS.currency_ada, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ada, R.string.currency_ada_short),
NormalUnit(MyUnitIDS.currency_aed, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_aed, R.string.currency_aed_short),
NormalUnit(MyUnitIDS.currency_afn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_afn, R.string.currency_afn_short),
NormalUnit(MyUnitIDS.currency_algo, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_algo, R.string.currency_algo_short),
NormalUnit(MyUnitIDS.currency_all, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_all, R.string.currency_all_short),
NormalUnit(MyUnitIDS.currency_amd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_amd, R.string.currency_amd_short),
NormalUnit(MyUnitIDS.currency_ang, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ang, R.string.currency_ang_short),
NormalUnit(MyUnitIDS.currency_aoa, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_aoa, R.string.currency_aoa_short),
NormalUnit(MyUnitIDS.currency_ars, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ars, R.string.currency_ars_short),
NormalUnit(MyUnitIDS.currency_atom, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_atom, R.string.currency_atom_short),
NormalUnit(MyUnitIDS.currency_aud, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_aud, R.string.currency_aud_short),
NormalUnit(MyUnitIDS.currency_avax, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_avax, R.string.currency_avax_short),
NormalUnit(MyUnitIDS.currency_awg, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_awg, R.string.currency_awg_short),
NormalUnit(MyUnitIDS.currency_azn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_azn, R.string.currency_azn_short),
NormalUnit(MyUnitIDS.currency_bam, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bam, R.string.currency_bam_short),
NormalUnit(MyUnitIDS.currency_bbd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bbd, R.string.currency_bbd_short),
NormalUnit(MyUnitIDS.currency_bch, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bch, R.string.currency_bch_short),
NormalUnit(MyUnitIDS.currency_bdt, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bdt, R.string.currency_bdt_short),
NormalUnit(MyUnitIDS.currency_bgn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bgn, R.string.currency_bgn_short),
NormalUnit(MyUnitIDS.currency_bhd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bhd, R.string.currency_bhd_short),
NormalUnit(MyUnitIDS.currency_bif, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bif, R.string.currency_bif_short),
NormalUnit(MyUnitIDS.currency_bmd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bmd, R.string.currency_bmd_short),
NormalUnit(MyUnitIDS.currency_bnb, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bnb, R.string.currency_bnb_short),
NormalUnit(MyUnitIDS.currency_bnd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bnd, R.string.currency_bnd_short),
NormalUnit(MyUnitIDS.currency_bob, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bob, R.string.currency_bob_short),
NormalUnit(MyUnitIDS.currency_brl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_brl, R.string.currency_brl_short),
NormalUnit(MyUnitIDS.currency_bsd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bsd, R.string.currency_bsd_short),
NormalUnit(MyUnitIDS.currency_btc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_btc, R.string.currency_btc_short),
NormalUnit(MyUnitIDS.currency_btn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_btn, R.string.currency_btn_short),
NormalUnit(MyUnitIDS.currency_busd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_busd, R.string.currency_busd_short),
NormalUnit(MyUnitIDS.currency_bwp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bwp, R.string.currency_bwp_short),
NormalUnit(MyUnitIDS.currency_byn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_byn, R.string.currency_byn_short),
NormalUnit(MyUnitIDS.currency_byr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_byr, R.string.currency_byr_short),
NormalUnit(MyUnitIDS.currency_bzd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_bzd, R.string.currency_bzd_short),
NormalUnit(MyUnitIDS.currency_cad, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cad, R.string.currency_cad_short),
NormalUnit(MyUnitIDS.currency_cdf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cdf, R.string.currency_cdf_short),
NormalUnit(MyUnitIDS.currency_chf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_chf, R.string.currency_chf_short),
NormalUnit(MyUnitIDS.currency_chz, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_chz, R.string.currency_chz_short),
NormalUnit(MyUnitIDS.currency_clf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_clf, R.string.currency_clf_short),
NormalUnit(MyUnitIDS.currency_clp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_clp, R.string.currency_clp_short),
NormalUnit(MyUnitIDS.currency_cny, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cny, R.string.currency_cny_short),
NormalUnit(MyUnitIDS.currency_cop, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cop, R.string.currency_cop_short),
NormalUnit(MyUnitIDS.currency_crc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_crc, R.string.currency_crc_short),
NormalUnit(MyUnitIDS.currency_cro, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cro, R.string.currency_cro_short),
NormalUnit(MyUnitIDS.currency_cuc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cuc, R.string.currency_cuc_short),
NormalUnit(MyUnitIDS.currency_cup, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cup, R.string.currency_cup_short),
NormalUnit(MyUnitIDS.currency_cve, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_cve, R.string.currency_cve_short),
NormalUnit(MyUnitIDS.currency_czk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_czk, R.string.currency_czk_short),
NormalUnit(MyUnitIDS.currency_dai, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_dai, R.string.currency_dai_short),
NormalUnit(MyUnitIDS.currency_djf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_djf, R.string.currency_djf_short),
NormalUnit(MyUnitIDS.currency_dkk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_dkk, R.string.currency_dkk_short),
NormalUnit(MyUnitIDS.currency_doge, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_doge, R.string.currency_doge_short),
NormalUnit(MyUnitIDS.currency_dop, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_dop, R.string.currency_dop_short),
NormalUnit(MyUnitIDS.currency_dot, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_dot, R.string.currency_dot_short),
NormalUnit(MyUnitIDS.currency_dzd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_dzd, R.string.currency_dzd_short),
NormalUnit(MyUnitIDS.currency_egld, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_egld, R.string.currency_egld_short),
NormalUnit(MyUnitIDS.currency_egp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_egp, R.string.currency_egp_short),
NormalUnit(MyUnitIDS.currency_enj, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_enj, R.string.currency_enj_short),
NormalUnit(MyUnitIDS.currency_ern, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ern, R.string.currency_ern_short),
NormalUnit(MyUnitIDS.currency_etb, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_etb, R.string.currency_etb_short),
NormalUnit(MyUnitIDS.currency_etc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_etc, R.string.currency_etc_short),
NormalUnit(MyUnitIDS.currency_eth, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_eth, R.string.currency_eth_short),
NormalUnit(MyUnitIDS.currency_eur, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_eur, R.string.currency_eur_short),
NormalUnit(MyUnitIDS.currency_fil, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_fil, R.string.currency_fil_short),
NormalUnit(MyUnitIDS.currency_fjd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_fjd, R.string.currency_fjd_short),
NormalUnit(MyUnitIDS.currency_fkp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_fkp, R.string.currency_fkp_short),
NormalUnit(MyUnitIDS.currency_ftt, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ftt, R.string.currency_ftt_short),
NormalUnit(MyUnitIDS.currency_gbp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_gbp, R.string.currency_gbp_short),
NormalUnit(MyUnitIDS.currency_gel, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_gel, R.string.currency_gel_short),
NormalUnit(MyUnitIDS.currency_ggp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ggp, R.string.currency_ggp_short),
NormalUnit(MyUnitIDS.currency_ghs, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ghs, R.string.currency_ghs_short),
NormalUnit(MyUnitIDS.currency_gip, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_gip, R.string.currency_gip_short),
NormalUnit(MyUnitIDS.currency_gmd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_gmd, R.string.currency_gmd_short),
NormalUnit(MyUnitIDS.currency_gnf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_gnf, R.string.currency_gnf_short),
NormalUnit(MyUnitIDS.currency_grt, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_grt, R.string.currency_grt_short),
NormalUnit(MyUnitIDS.currency_gtq, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_gtq, R.string.currency_gtq_short),
NormalUnit(MyUnitIDS.currency_gyd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_gyd, R.string.currency_gyd_short),
NormalUnit(MyUnitIDS.currency_hkd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_hkd, R.string.currency_hkd_short),
NormalUnit(MyUnitIDS.currency_hnl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_hnl, R.string.currency_hnl_short),
NormalUnit(MyUnitIDS.currency_hrk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_hrk, R.string.currency_hrk_short),
NormalUnit(MyUnitIDS.currency_htg, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_htg, R.string.currency_htg_short),
NormalUnit(MyUnitIDS.currency_huf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_huf, R.string.currency_huf_short),
NormalUnit(MyUnitIDS.currency_icp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_icp, R.string.currency_icp_short),
NormalUnit(MyUnitIDS.currency_idr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_idr, R.string.currency_idr_short),
NormalUnit(MyUnitIDS.currency_ils, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ils, R.string.currency_ils_short),
NormalUnit(MyUnitIDS.currency_imp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_imp, R.string.currency_imp_short),
NormalUnit(MyUnitIDS.currency_inj, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_inj, R.string.currency_inj_short),
NormalUnit(MyUnitIDS.currency_inr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_inr, R.string.currency_inr_short),
NormalUnit(MyUnitIDS.currency_iqd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_iqd, R.string.currency_iqd_short),
NormalUnit(MyUnitIDS.currency_irr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_irr, R.string.currency_irr_short),
NormalUnit(MyUnitIDS.currency_isk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_isk, R.string.currency_isk_short),
NormalUnit(MyUnitIDS.currency_jep, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_jep, R.string.currency_jep_short),
NormalUnit(MyUnitIDS.currency_jmd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_jmd, R.string.currency_jmd_short),
NormalUnit(MyUnitIDS.currency_jod, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_jod, R.string.currency_jod_short),
NormalUnit(MyUnitIDS.currency_jpy, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_jpy, R.string.currency_jpy_short),
NormalUnit(MyUnitIDS.currency_kes, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_kes, R.string.currency_kes_short),
NormalUnit(MyUnitIDS.currency_kgs, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_kgs, R.string.currency_kgs_short),
NormalUnit(MyUnitIDS.currency_khr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_khr, R.string.currency_khr_short),
NormalUnit(MyUnitIDS.currency_kmf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_kmf, R.string.currency_kmf_short),
NormalUnit(MyUnitIDS.currency_kpw, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_kpw, R.string.currency_kpw_short),
NormalUnit(MyUnitIDS.currency_krw, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_krw, R.string.currency_krw_short),
NormalUnit(MyUnitIDS.currency_ksm, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ksm, R.string.currency_ksm_short),
NormalUnit(MyUnitIDS.currency_kwd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_kwd, R.string.currency_kwd_short),
NormalUnit(MyUnitIDS.currency_kyd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_kyd, R.string.currency_kyd_short),
NormalUnit(MyUnitIDS.currency_kzt, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_kzt, R.string.currency_kzt_short),
NormalUnit(MyUnitIDS.currency_lak, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_lak, R.string.currency_lak_short),
NormalUnit(MyUnitIDS.currency_lbp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_lbp, R.string.currency_lbp_short),
NormalUnit(MyUnitIDS.currency_link, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_link, R.string.currency_link_short),
NormalUnit(MyUnitIDS.currency_lkr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_lkr, R.string.currency_lkr_short),
NormalUnit(MyUnitIDS.currency_lrd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_lrd, R.string.currency_lrd_short),
NormalUnit(MyUnitIDS.currency_lsl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_lsl, R.string.currency_lsl_short),
NormalUnit(MyUnitIDS.currency_ltc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ltc, R.string.currency_ltc_short),
NormalUnit(MyUnitIDS.currency_ltl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ltl, R.string.currency_ltl_short),
NormalUnit(MyUnitIDS.currency_luna, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_luna, R.string.currency_luna_short),
NormalUnit(MyUnitIDS.currency_lvl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_lvl, R.string.currency_lvl_short),
NormalUnit(MyUnitIDS.currency_lyd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_lyd, R.string.currency_lyd_short),
NormalUnit(MyUnitIDS.currency_mad, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mad, R.string.currency_mad_short),
NormalUnit(MyUnitIDS.currency_matic, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_matic, R.string.currency_matic_short),
NormalUnit(MyUnitIDS.currency_mdl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mdl, R.string.currency_mdl_short),
NormalUnit(MyUnitIDS.currency_mga, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mga, R.string.currency_mga_short),
NormalUnit(MyUnitIDS.currency_mkd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mkd, R.string.currency_mkd_short),
NormalUnit(MyUnitIDS.currency_mmk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mmk, R.string.currency_mmk_short),
NormalUnit(MyUnitIDS.currency_mnt, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mnt, R.string.currency_mnt_short),
NormalUnit(MyUnitIDS.currency_mop, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mop, R.string.currency_mop_short),
NormalUnit(MyUnitIDS.currency_mro, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mro, R.string.currency_mro_short),
NormalUnit(MyUnitIDS.currency_mur, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mur, R.string.currency_mur_short),
NormalUnit(MyUnitIDS.currency_mvr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mvr, R.string.currency_mvr_short),
NormalUnit(MyUnitIDS.currency_mwk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mwk, R.string.currency_mwk_short),
NormalUnit(MyUnitIDS.currency_mxn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mxn, R.string.currency_mxn_short),
NormalUnit(MyUnitIDS.currency_myr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_myr, R.string.currency_myr_short),
NormalUnit(MyUnitIDS.currency_mzn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_mzn, R.string.currency_mzn_short),
NormalUnit(MyUnitIDS.currency_nad, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_nad, R.string.currency_nad_short),
NormalUnit(MyUnitIDS.currency_ngn, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ngn, R.string.currency_ngn_short),
NormalUnit(MyUnitIDS.currency_nio, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_nio, R.string.currency_nio_short),
NormalUnit(MyUnitIDS.currency_nok, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_nok, R.string.currency_nok_short),
NormalUnit(MyUnitIDS.currency_npr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_npr, R.string.currency_npr_short),
NormalUnit(MyUnitIDS.currency_nzd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_nzd, R.string.currency_nzd_short),
NormalUnit(MyUnitIDS.currency_omr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_omr, R.string.currency_omr_short),
NormalUnit(MyUnitIDS.currency_one, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_one, R.string.currency_one_short),
NormalUnit(MyUnitIDS.currency_pab, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_pab, R.string.currency_pab_short),
NormalUnit(MyUnitIDS.currency_pen, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_pen, R.string.currency_pen_short),
NormalUnit(MyUnitIDS.currency_pgk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_pgk, R.string.currency_pgk_short),
NormalUnit(MyUnitIDS.currency_php, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_php, R.string.currency_php_short),
NormalUnit(MyUnitIDS.currency_pkr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_pkr, R.string.currency_pkr_short),
NormalUnit(MyUnitIDS.currency_pln, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_pln, R.string.currency_pln_short),
NormalUnit(MyUnitIDS.currency_pyg, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_pyg, R.string.currency_pyg_short),
NormalUnit(MyUnitIDS.currency_qar, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_qar, R.string.currency_qar_short),
NormalUnit(MyUnitIDS.currency_ron, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ron, R.string.currency_ron_short),
NormalUnit(MyUnitIDS.currency_rsd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_rsd, R.string.currency_rsd_short),
NormalUnit(MyUnitIDS.currency_rub, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_rub, R.string.currency_rub_short),
NormalUnit(MyUnitIDS.currency_rwf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_rwf, R.string.currency_rwf_short),
NormalUnit(MyUnitIDS.currency_sar, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sar, R.string.currency_sar_short),
NormalUnit(MyUnitIDS.currency_sbd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sbd, R.string.currency_sbd_short),
NormalUnit(MyUnitIDS.currency_scr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_scr, R.string.currency_scr_short),
NormalUnit(MyUnitIDS.currency_sdg, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sdg, R.string.currency_sdg_short),
NormalUnit(MyUnitIDS.currency_sek, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sek, R.string.currency_sek_short),
NormalUnit(MyUnitIDS.currency_sgd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sgd, R.string.currency_sgd_short),
NormalUnit(MyUnitIDS.currency_shib, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_shib, R.string.currency_shib_short),
NormalUnit(MyUnitIDS.currency_shp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_shp, R.string.currency_shp_short),
NormalUnit(MyUnitIDS.currency_sll, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sll, R.string.currency_sll_short),
NormalUnit(MyUnitIDS.currency_sol, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sol, R.string.currency_sol_short),
NormalUnit(MyUnitIDS.currency_sos, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_sos, R.string.currency_sos_short),
NormalUnit(MyUnitIDS.currency_srd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_srd, R.string.currency_srd_short),
NormalUnit(MyUnitIDS.currency_std, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_std, R.string.currency_std_short),
NormalUnit(MyUnitIDS.currency_svc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_svc, R.string.currency_svc_short),
NormalUnit(MyUnitIDS.currency_syp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_syp, R.string.currency_syp_short),
NormalUnit(MyUnitIDS.currency_szl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_szl, R.string.currency_szl_short),
NormalUnit(MyUnitIDS.currency_thb, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_thb, R.string.currency_thb_short),
NormalUnit(MyUnitIDS.currency_theta, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_theta, R.string.currency_theta_short),
NormalUnit(MyUnitIDS.currency_tjs, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_tjs, R.string.currency_tjs_short),
NormalUnit(MyUnitIDS.currency_tmt, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_tmt, R.string.currency_tmt_short),
NormalUnit(MyUnitIDS.currency_tnd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_tnd, R.string.currency_tnd_short),
NormalUnit(MyUnitIDS.currency_top, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_top, R.string.currency_top_short),
NormalUnit(MyUnitIDS.currency_trx, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_trx, R.string.currency_trx_short),
NormalUnit(MyUnitIDS.currency_try, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_try, R.string.currency_try_short),
NormalUnit(MyUnitIDS.currency_ttd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ttd, R.string.currency_ttd_short),
NormalUnit(MyUnitIDS.currency_twd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_twd, R.string.currency_twd_short),
NormalUnit(MyUnitIDS.currency_tzs, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_tzs, R.string.currency_tzs_short),
NormalUnit(MyUnitIDS.currency_uah, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_uah, R.string.currency_uah_short),
NormalUnit(MyUnitIDS.currency_ugx, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_ugx, R.string.currency_ugx_short),
NormalUnit(MyUnitIDS.currency_uni, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_uni, R.string.currency_uni_short),
NormalUnit(MyUnitIDS.currency_usd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_usd, R.string.currency_usd_short),
NormalUnit(MyUnitIDS.currency_usdc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_usdc, R.string.currency_usdc_short),
NormalUnit(MyUnitIDS.currency_usdt, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_usdt, R.string.currency_usdt_short),
NormalUnit(MyUnitIDS.currency_uyu, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_uyu, R.string.currency_uyu_short),
NormalUnit(MyUnitIDS.currency_uzs, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_uzs, R.string.currency_uzs_short),
NormalUnit(MyUnitIDS.currency_vef, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_vef, R.string.currency_vef_short),
NormalUnit(MyUnitIDS.currency_vet, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_vet, R.string.currency_vet_short),
NormalUnit(MyUnitIDS.currency_vnd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_vnd, R.string.currency_vnd_short),
NormalUnit(MyUnitIDS.currency_vuv, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_vuv, R.string.currency_vuv_short),
NormalUnit(MyUnitIDS.currency_wbtc, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_wbtc, R.string.currency_wbtc_short),
NormalUnit(MyUnitIDS.currency_wst, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_wst, R.string.currency_wst_short),
NormalUnit(MyUnitIDS.currency_xaf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xaf, R.string.currency_xaf_short),
NormalUnit(MyUnitIDS.currency_xag, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xag, R.string.currency_xag_short),
NormalUnit(MyUnitIDS.currency_xau, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xau, R.string.currency_xau_short),
NormalUnit(MyUnitIDS.currency_xcd, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xcd, R.string.currency_xcd_short),
NormalUnit(MyUnitIDS.currency_xdr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xdr, R.string.currency_xdr_short),
NormalUnit(MyUnitIDS.currency_xlm, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xlm, R.string.currency_xlm_short),
NormalUnit(MyUnitIDS.currency_xmr, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xmr, R.string.currency_xmr_short),
NormalUnit(MyUnitIDS.currency_xof, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xof, R.string.currency_xof_short),
NormalUnit(MyUnitIDS.currency_xpf, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xpf, R.string.currency_xpf_short),
NormalUnit(MyUnitIDS.currency_xrp, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_xrp, R.string.currency_xrp_short),
NormalUnit(MyUnitIDS.currency_yer, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_yer, R.string.currency_yer_short),
NormalUnit(MyUnitIDS.currency_zar, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_zar, R.string.currency_zar_short),
NormalUnit(MyUnitIDS.currency_zmk, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_zmk, R.string.currency_zmk_short),
NormalUnit(MyUnitIDS.currency_zmw, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_zmw, R.string.currency_zmw_short),
NormalUnit(MyUnitIDS.currency_zwl, BigDecimal.ONE, UnitGroup.CURRENCY, R.string.currency_zwl, R.string.currency_zwl_short),
)
}
}

View File

@ -19,33 +19,33 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val dataCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.bit, BigDecimal.valueOf(1), UnitGroup.DATA, R.string.bit, R.string.bit_short),
DefaultUnit(MyUnitIDS.kibibit, BigDecimal.valueOf(1_024), UnitGroup.DATA, R.string.kibibit, R.string.kibibit_short),
DefaultUnit(MyUnitIDS.kilobit, BigDecimal.valueOf(1_000), UnitGroup.DATA, R.string.kilobit, R.string.kilobit_short),
DefaultUnit(MyUnitIDS.megabit, BigDecimal.valueOf(1_000_000), UnitGroup.DATA, R.string.megabit, R.string.megabit_short),
DefaultUnit(MyUnitIDS.mebibit, BigDecimal.valueOf(1_048_576), UnitGroup.DATA, R.string.mebibit, R.string.mebibit_short),
DefaultUnit(MyUnitIDS.gigabit, BigDecimal.valueOf(1_000_000_000), UnitGroup.DATA, R.string.gigabit, R.string.gigabit_short),
DefaultUnit(MyUnitIDS.gibibit, BigDecimal.valueOf(1_073_741_824), UnitGroup.DATA, R.string.gibibit, R.string.gibibit_short),
DefaultUnit(MyUnitIDS.terabit, BigDecimal.valueOf(1_000_000_000_000), UnitGroup.DATA, R.string.terabit, R.string.terabit_short),
DefaultUnit(MyUnitIDS.petabit, BigDecimal.valueOf(1_000_000_000_000_000), UnitGroup.DATA, R.string.petabit, R.string.petabit_short),
DefaultUnit(MyUnitIDS.exabit, BigDecimal.valueOf(1_000_000_000_000_000_000), UnitGroup.DATA, R.string.exabit, R.string.exabit_short),
DefaultUnit(MyUnitIDS.byte, BigDecimal.valueOf(8), UnitGroup.DATA, R.string.byte_, R.string.byte_short),
DefaultUnit(MyUnitIDS.kibibyte, BigDecimal.valueOf(8_192), UnitGroup.DATA, R.string.kibibyte, R.string.kibibyte_short),
DefaultUnit(MyUnitIDS.kilobyte, BigDecimal.valueOf(8_000), UnitGroup.DATA, R.string.kilobyte, R.string.kilobyte_short),
DefaultUnit(MyUnitIDS.megabyte, BigDecimal.valueOf(8_000_000), UnitGroup.DATA, R.string.megabyte, R.string.megabyte_short),
DefaultUnit(MyUnitIDS.mebibyte, BigDecimal.valueOf(8_388_608), UnitGroup.DATA, R.string.mebibyte, R.string.mebibyte_short),
DefaultUnit(MyUnitIDS.gigabyte, BigDecimal.valueOf(8_000_000_000), UnitGroup.DATA, R.string.gigabyte, R.string.gigabyte_short),
DefaultUnit(MyUnitIDS.gibibyte, BigDecimal.valueOf(8_589_934_592), UnitGroup.DATA, R.string.gibibyte, R.string.gibibyte_short),
DefaultUnit(MyUnitIDS.terabyte, BigDecimal.valueOf(8_000_000_000_000), UnitGroup.DATA, R.string.terabyte, R.string.terabyte_short),
DefaultUnit(MyUnitIDS.petabyte, BigDecimal.valueOf(8_000_000_000_000_000), UnitGroup.DATA, R.string.petabyte, R.string.petabyte_short),
DefaultUnit(MyUnitIDS.exabyte, BigDecimal.valueOf(8_000_000_000_000_000_000), UnitGroup.DATA, R.string.exabyte, R.string.exabyte_short),
NormalUnit(MyUnitIDS.bit, BigDecimal.valueOf(1), UnitGroup.DATA, R.string.bit, R.string.bit_short),
NormalUnit(MyUnitIDS.kibibit, BigDecimal.valueOf(1_024), UnitGroup.DATA, R.string.kibibit, R.string.kibibit_short),
NormalUnit(MyUnitIDS.kilobit, BigDecimal.valueOf(1_000), UnitGroup.DATA, R.string.kilobit, R.string.kilobit_short),
NormalUnit(MyUnitIDS.megabit, BigDecimal.valueOf(1_000_000), UnitGroup.DATA, R.string.megabit, R.string.megabit_short),
NormalUnit(MyUnitIDS.mebibit, BigDecimal.valueOf(1_048_576), UnitGroup.DATA, R.string.mebibit, R.string.mebibit_short),
NormalUnit(MyUnitIDS.gigabit, BigDecimal.valueOf(1_000_000_000), UnitGroup.DATA, R.string.gigabit, R.string.gigabit_short),
NormalUnit(MyUnitIDS.gibibit, BigDecimal.valueOf(1_073_741_824), UnitGroup.DATA, R.string.gibibit, R.string.gibibit_short),
NormalUnit(MyUnitIDS.terabit, BigDecimal.valueOf(1_000_000_000_000), UnitGroup.DATA, R.string.terabit, R.string.terabit_short),
NormalUnit(MyUnitIDS.petabit, BigDecimal.valueOf(1_000_000_000_000_000), UnitGroup.DATA, R.string.petabit, R.string.petabit_short),
NormalUnit(MyUnitIDS.exabit, BigDecimal.valueOf(1_000_000_000_000_000_000), UnitGroup.DATA, R.string.exabit, R.string.exabit_short),
NormalUnit(MyUnitIDS.byte, BigDecimal.valueOf(8), UnitGroup.DATA, R.string.byte_, R.string.byte_short),
NormalUnit(MyUnitIDS.kibibyte, BigDecimal.valueOf(8_192), UnitGroup.DATA, R.string.kibibyte, R.string.kibibyte_short),
NormalUnit(MyUnitIDS.kilobyte, BigDecimal.valueOf(8_000), UnitGroup.DATA, R.string.kilobyte, R.string.kilobyte_short),
NormalUnit(MyUnitIDS.megabyte, BigDecimal.valueOf(8_000_000), UnitGroup.DATA, R.string.megabyte, R.string.megabyte_short),
NormalUnit(MyUnitIDS.mebibyte, BigDecimal.valueOf(8_388_608), UnitGroup.DATA, R.string.mebibyte, R.string.mebibyte_short),
NormalUnit(MyUnitIDS.gigabyte, BigDecimal.valueOf(8_000_000_000), UnitGroup.DATA, R.string.gigabyte, R.string.gigabyte_short),
NormalUnit(MyUnitIDS.gibibyte, BigDecimal.valueOf(8_589_934_592), UnitGroup.DATA, R.string.gibibyte, R.string.gibibyte_short),
NormalUnit(MyUnitIDS.terabyte, BigDecimal.valueOf(8_000_000_000_000), UnitGroup.DATA, R.string.terabyte, R.string.terabyte_short),
NormalUnit(MyUnitIDS.petabyte, BigDecimal.valueOf(8_000_000_000_000_000), UnitGroup.DATA, R.string.petabyte, R.string.petabyte_short),
NormalUnit(MyUnitIDS.exabyte, BigDecimal.valueOf(8_000_000_000_000_000_000), UnitGroup.DATA, R.string.exabyte, R.string.exabyte_short),
)
}
}

View File

@ -19,33 +19,33 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val dataTransferCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.bit_per_second, BigDecimal.valueOf(1), UnitGroup.DATA_TRANSFER, R.string.bit_per_second, R.string.bit_per_second_short),
DefaultUnit(MyUnitIDS.kibibit_per_second, BigDecimal.valueOf(1_024), UnitGroup.DATA_TRANSFER, R.string.kibibit_per_second, R.string.kibibit_per_second_short),
DefaultUnit(MyUnitIDS.kilobit_per_second, BigDecimal.valueOf(1_000), UnitGroup.DATA_TRANSFER, R.string.kilobit_per_second, R.string.kilobit_per_second_short),
DefaultUnit(MyUnitIDS.megabit_per_second, BigDecimal.valueOf(1_000_000), UnitGroup.DATA_TRANSFER, R.string.megabit_per_second, R.string.megabit_per_second_short),
DefaultUnit(MyUnitIDS.mebibit_per_second, BigDecimal.valueOf(1_048_576), UnitGroup.DATA_TRANSFER, R.string.mebibit_per_second, R.string.mebibit_per_second_short),
DefaultUnit(MyUnitIDS.gigabit_per_second, BigDecimal.valueOf(1_000_000_000), UnitGroup.DATA_TRANSFER, R.string.gigabit_per_second, R.string.gigabit_per_second_short),
DefaultUnit(MyUnitIDS.gibibit_per_second, BigDecimal.valueOf(1_073_741_824), UnitGroup.DATA_TRANSFER, R.string.gibibit_per_second, R.string.gibibit_per_second_short),
DefaultUnit(MyUnitIDS.terabit_per_second, BigDecimal.valueOf(1_000_000_000_000), UnitGroup.DATA_TRANSFER, R.string.terabit_per_second, R.string.terabit_per_second_short),
DefaultUnit(MyUnitIDS.petabit_per_second, BigDecimal.valueOf(1_000_000_000_000_000), UnitGroup.DATA_TRANSFER, R.string.petabit_per_second, R.string.petabit_per_second_short),
DefaultUnit(MyUnitIDS.exabit_per_second, BigDecimal.valueOf(1_000_000_000_000_000_000), UnitGroup.DATA_TRANSFER, R.string.exabit_per_second, R.string.exabit_per_second_short),
DefaultUnit(MyUnitIDS.byte_per_second, BigDecimal.valueOf(8), UnitGroup.DATA_TRANSFER, R.string.byte_per_second, R.string.byte_per_second_short),
DefaultUnit(MyUnitIDS.kibibyte_per_second, BigDecimal.valueOf(8_192), UnitGroup.DATA_TRANSFER, R.string.kibibyte_per_second, R.string.kibibyte_per_second_short),
DefaultUnit(MyUnitIDS.kilobyte_per_second, BigDecimal.valueOf(8_000), UnitGroup.DATA_TRANSFER, R.string.kilobyte_per_second, R.string.kilobyte_per_second_short),
DefaultUnit(MyUnitIDS.megabyte_per_second, BigDecimal.valueOf(8_000_000), UnitGroup.DATA_TRANSFER, R.string.megabyte_per_second, R.string.megabyte_per_second_short),
DefaultUnit(MyUnitIDS.mebibyte_per_second, BigDecimal.valueOf(8_388_608), UnitGroup.DATA_TRANSFER, R.string.mebibyte_per_second, R.string.mebibyte_per_second_short),
DefaultUnit(MyUnitIDS.gigabyte_per_second, BigDecimal.valueOf(8_000_000_000), UnitGroup.DATA_TRANSFER, R.string.gigabyte_per_second, R.string.gigabyte_per_second_short),
DefaultUnit(MyUnitIDS.gibibyte_per_second, BigDecimal.valueOf(8_589_934_592), UnitGroup.DATA_TRANSFER, R.string.gibibyte_per_second, R.string.gibibyte_per_second_short),
DefaultUnit(MyUnitIDS.terabyte_per_second, BigDecimal.valueOf(8_000_000_000_000), UnitGroup.DATA_TRANSFER, R.string.terabyte_per_second, R.string.terabyte_per_second_short),
DefaultUnit(MyUnitIDS.petabyte_per_second, BigDecimal.valueOf(8_000_000_000_000_000), UnitGroup.DATA_TRANSFER, R.string.petabyte_per_second, R.string.petabyte_per_second_short),
DefaultUnit(MyUnitIDS.exabyte_per_second, BigDecimal.valueOf(8_000_000_000_000_000_000), UnitGroup.DATA_TRANSFER, R.string.exabyte_per_second, R.string.exabyte_per_second_short),
NormalUnit(MyUnitIDS.bit_per_second, BigDecimal.valueOf(1), UnitGroup.DATA_TRANSFER, R.string.bit_per_second, R.string.bit_per_second_short),
NormalUnit(MyUnitIDS.kibibit_per_second, BigDecimal.valueOf(1_024), UnitGroup.DATA_TRANSFER, R.string.kibibit_per_second, R.string.kibibit_per_second_short),
NormalUnit(MyUnitIDS.kilobit_per_second, BigDecimal.valueOf(1_000), UnitGroup.DATA_TRANSFER, R.string.kilobit_per_second, R.string.kilobit_per_second_short),
NormalUnit(MyUnitIDS.megabit_per_second, BigDecimal.valueOf(1_000_000), UnitGroup.DATA_TRANSFER, R.string.megabit_per_second, R.string.megabit_per_second_short),
NormalUnit(MyUnitIDS.mebibit_per_second, BigDecimal.valueOf(1_048_576), UnitGroup.DATA_TRANSFER, R.string.mebibit_per_second, R.string.mebibit_per_second_short),
NormalUnit(MyUnitIDS.gigabit_per_second, BigDecimal.valueOf(1_000_000_000), UnitGroup.DATA_TRANSFER, R.string.gigabit_per_second, R.string.gigabit_per_second_short),
NormalUnit(MyUnitIDS.gibibit_per_second, BigDecimal.valueOf(1_073_741_824), UnitGroup.DATA_TRANSFER, R.string.gibibit_per_second, R.string.gibibit_per_second_short),
NormalUnit(MyUnitIDS.terabit_per_second, BigDecimal.valueOf(1_000_000_000_000), UnitGroup.DATA_TRANSFER, R.string.terabit_per_second, R.string.terabit_per_second_short),
NormalUnit(MyUnitIDS.petabit_per_second, BigDecimal.valueOf(1_000_000_000_000_000), UnitGroup.DATA_TRANSFER, R.string.petabit_per_second, R.string.petabit_per_second_short),
NormalUnit(MyUnitIDS.exabit_per_second, BigDecimal.valueOf(1_000_000_000_000_000_000), UnitGroup.DATA_TRANSFER, R.string.exabit_per_second, R.string.exabit_per_second_short),
NormalUnit(MyUnitIDS.byte_per_second, BigDecimal.valueOf(8), UnitGroup.DATA_TRANSFER, R.string.byte_per_second, R.string.byte_per_second_short),
NormalUnit(MyUnitIDS.kibibyte_per_second, BigDecimal.valueOf(8_192), UnitGroup.DATA_TRANSFER, R.string.kibibyte_per_second, R.string.kibibyte_per_second_short),
NormalUnit(MyUnitIDS.kilobyte_per_second, BigDecimal.valueOf(8_000), UnitGroup.DATA_TRANSFER, R.string.kilobyte_per_second, R.string.kilobyte_per_second_short),
NormalUnit(MyUnitIDS.megabyte_per_second, BigDecimal.valueOf(8_000_000), UnitGroup.DATA_TRANSFER, R.string.megabyte_per_second, R.string.megabyte_per_second_short),
NormalUnit(MyUnitIDS.mebibyte_per_second, BigDecimal.valueOf(8_388_608), UnitGroup.DATA_TRANSFER, R.string.mebibyte_per_second, R.string.mebibyte_per_second_short),
NormalUnit(MyUnitIDS.gigabyte_per_second, BigDecimal.valueOf(8_000_000_000), UnitGroup.DATA_TRANSFER, R.string.gigabyte_per_second, R.string.gigabyte_per_second_short),
NormalUnit(MyUnitIDS.gibibyte_per_second, BigDecimal.valueOf(8_589_934_592), UnitGroup.DATA_TRANSFER, R.string.gibibyte_per_second, R.string.gibibyte_per_second_short),
NormalUnit(MyUnitIDS.terabyte_per_second, BigDecimal.valueOf(8_000_000_000_000), UnitGroup.DATA_TRANSFER, R.string.terabyte_per_second, R.string.terabyte_per_second_short),
NormalUnit(MyUnitIDS.petabyte_per_second, BigDecimal.valueOf(8_000_000_000_000_000), UnitGroup.DATA_TRANSFER, R.string.petabyte_per_second, R.string.petabyte_per_second_short),
NormalUnit(MyUnitIDS.exabyte_per_second, BigDecimal.valueOf(8_000_000_000_000_000_000), UnitGroup.DATA_TRANSFER, R.string.exabyte_per_second, R.string.exabyte_per_second_short),
)
}
}

View File

@ -0,0 +1,43 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val electrostaticCapacitance: List<AbstractUnit> by lazy {
listOf(
NormalUnit(MyUnitIDS.attofarad, BigDecimal.valueOf(1), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.attofarad, R.string.attofarad_short),
NormalUnit(MyUnitIDS.picofarad, BigDecimal.valueOf(1E+6), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.picofarad, R.string.picofarad_short),
NormalUnit(MyUnitIDS.statfarad, BigDecimal.valueOf(1112650.0561), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.statfarad, R.string.statfarad_short),
NormalUnit(MyUnitIDS.nanofarad, BigDecimal.valueOf(1E+9), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.nanofarad, R.string.nanofarad_short),
NormalUnit(MyUnitIDS.microfarad, BigDecimal.valueOf(1E+12), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.microfarad, R.string.microfarad_short),
NormalUnit(MyUnitIDS.millifarad, BigDecimal.valueOf(1E+15), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.millifarad, R.string.millifarad_short),
NormalUnit(MyUnitIDS.farad, BigDecimal.valueOf(1E+18), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.farad, R.string.farad_short),
NormalUnit(MyUnitIDS.kilofarad, BigDecimal.valueOf(1E+21), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.kilofarad, R.string.kilofarad_short),
NormalUnit(MyUnitIDS.megafarad, BigDecimal.valueOf(1E+24), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.megafarad, R.string.megafarad_short),
NormalUnit(MyUnitIDS.gigafarad, BigDecimal.valueOf(1E+27), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.gigafarad, R.string.gigafarad_short),
NormalUnit(MyUnitIDS.petafarad, BigDecimal.valueOf(1E+33), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.petafarad, R.string.petafarad_short),
NormalUnit(MyUnitIDS.exafarad, BigDecimal.valueOf(1E+36), UnitGroup.ELECTROSTATIC_CAPACITANCE, R.string.exafarad, R.string.exafarad_short),
)
}

View File

@ -19,26 +19,26 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val energyCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.electron_volt, BigDecimal.valueOf(0.160217733), UnitGroup.ENERGY, R.string.electron_volt, R.string.electron_volt_short),
DefaultUnit(MyUnitIDS.attojoule, BigDecimal.valueOf(1), UnitGroup.ENERGY, R.string.attojoule, R.string.attojoule_short),
DefaultUnit(MyUnitIDS.joule, BigDecimal.valueOf(1E+18), UnitGroup.ENERGY, R.string.joule, R.string.joule_short),
DefaultUnit(MyUnitIDS.kilojoule, BigDecimal.valueOf(1E+21), UnitGroup.ENERGY, R.string.kilojoule, R.string.kilojoule_short),
DefaultUnit(MyUnitIDS.megajoule, BigDecimal.valueOf(1E+24), UnitGroup.ENERGY, R.string.megajoule, R.string.megajoule_short),
DefaultUnit(MyUnitIDS.gigajoule, BigDecimal.valueOf(1E+27), UnitGroup.ENERGY, R.string.gigajoule, R.string.gigajoule_short),
DefaultUnit(MyUnitIDS.energy_ton, BigDecimal.valueOf(4.184E+27), UnitGroup.ENERGY, R.string.energy_ton, R.string.energy_ton_short),
DefaultUnit(MyUnitIDS.kiloton, BigDecimal.valueOf(4.184E+30), UnitGroup.ENERGY, R.string.kiloton, R.string.kiloton_short),
DefaultUnit(MyUnitIDS.megaton, BigDecimal.valueOf(4.184E+33), UnitGroup.ENERGY, R.string.megaton, R.string.megaton_short),
DefaultUnit(MyUnitIDS.gigaton, BigDecimal.valueOf(4.184E+36), UnitGroup.ENERGY, R.string.gigaton, R.string.gigaton_short),
DefaultUnit(MyUnitIDS.energy_horse_power_metric, BigDecimal.valueOf(2.6477955E+24), UnitGroup.ENERGY, R.string.energy_horse_power_metric, R.string.energy_horse_power_metric_short),
DefaultUnit(MyUnitIDS.calorie_th, BigDecimal.valueOf(4184E+15), UnitGroup.ENERGY, R.string.calorie_th, R.string.calorie_th_short),
DefaultUnit(MyUnitIDS.kilocalorie_th, BigDecimal.valueOf(4184E+18), UnitGroup.ENERGY, R.string.kilocalorie_th, R.string.kilocalorie_th_short),
NormalUnit(MyUnitIDS.electron_volt, BigDecimal.valueOf(0.160217733), UnitGroup.ENERGY, R.string.electron_volt, R.string.electron_volt_short),
NormalUnit(MyUnitIDS.attojoule, BigDecimal.valueOf(1), UnitGroup.ENERGY, R.string.attojoule, R.string.attojoule_short),
NormalUnit(MyUnitIDS.joule, BigDecimal.valueOf(1E+18), UnitGroup.ENERGY, R.string.joule, R.string.joule_short),
NormalUnit(MyUnitIDS.kilojoule, BigDecimal.valueOf(1E+21), UnitGroup.ENERGY, R.string.kilojoule, R.string.kilojoule_short),
NormalUnit(MyUnitIDS.megajoule, BigDecimal.valueOf(1E+24), UnitGroup.ENERGY, R.string.megajoule, R.string.megajoule_short),
NormalUnit(MyUnitIDS.gigajoule, BigDecimal.valueOf(1E+27), UnitGroup.ENERGY, R.string.gigajoule, R.string.gigajoule_short),
NormalUnit(MyUnitIDS.energy_ton, BigDecimal.valueOf(4.184E+27), UnitGroup.ENERGY, R.string.energy_ton, R.string.energy_ton_short),
NormalUnit(MyUnitIDS.kiloton, BigDecimal.valueOf(4.184E+30), UnitGroup.ENERGY, R.string.kiloton, R.string.kiloton_short),
NormalUnit(MyUnitIDS.megaton, BigDecimal.valueOf(4.184E+33), UnitGroup.ENERGY, R.string.megaton, R.string.megaton_short),
NormalUnit(MyUnitIDS.gigaton, BigDecimal.valueOf(4.184E+36), UnitGroup.ENERGY, R.string.gigaton, R.string.gigaton_short),
NormalUnit(MyUnitIDS.energy_horse_power_metric, BigDecimal.valueOf(2.6477955E+24), UnitGroup.ENERGY, R.string.energy_horse_power_metric, R.string.energy_horse_power_metric_short),
NormalUnit(MyUnitIDS.calorie_th, BigDecimal.valueOf(4184E+15), UnitGroup.ENERGY, R.string.calorie_th, R.string.calorie_th_short),
NormalUnit(MyUnitIDS.kilocalorie_th, BigDecimal.valueOf(4184E+18), UnitGroup.ENERGY, R.string.kilocalorie_th, R.string.kilocalorie_th_short),
)
}
}

View File

@ -19,34 +19,34 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.FlowRateUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.ReverseUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
val flowRateCollection: List<AbstractUnit> by lazy {
listOf(
FlowRateUnit(MyUnitIDS.liter_per_hour, BigDecimal.valueOf(3600000), UnitGroup.FLOW_RATE, R.string.liter_per_hour, R.string.liter_per_hour_short),
FlowRateUnit(MyUnitIDS.liter_per_minute, BigDecimal.valueOf(60000), UnitGroup.FLOW_RATE, R.string.liter_per_minute, R.string.liter_per_minute_short),
FlowRateUnit(MyUnitIDS.liter_per_second, BigDecimal.valueOf(1000), UnitGroup.FLOW_RATE, R.string.liter_per_second, R.string.liter_per_second_short),
FlowRateUnit(MyUnitIDS.milliliter_per_hour, BigDecimal.valueOf(3600000000), UnitGroup.FLOW_RATE, R.string.milliliter_per_hour, R.string.milliliter_per_hour_short),
FlowRateUnit(MyUnitIDS.milliliter_per_minute, BigDecimal.valueOf(60000000), UnitGroup.FLOW_RATE, R.string.milliliter_per_minute, R.string.milliliter_per_minute_short),
FlowRateUnit(MyUnitIDS.milliliter_per_second, BigDecimal.valueOf(1000000), UnitGroup.FLOW_RATE, R.string.milliliter_per_second, R.string.milliliter_per_second_short),
FlowRateUnit(MyUnitIDS.cubic_meter_per_hour, BigDecimal.valueOf(3600), UnitGroup.FLOW_RATE, R.string.cubic_meter_per_hour, R.string.cubic_meter_per_hour_short),
FlowRateUnit(MyUnitIDS.cubic_meter_per_minute, BigDecimal.valueOf(60), UnitGroup.FLOW_RATE, R.string.cubic_meter_per_minute, R.string.cubic_meter_per_minute_short),
FlowRateUnit(MyUnitIDS.cubic_meter_per_second, BigDecimal.valueOf(1), UnitGroup.FLOW_RATE, R.string.cubic_meter_per_second, R.string.cubic_meter_per_second_short),
FlowRateUnit(MyUnitIDS.cubic_millimeter_per_hour, BigDecimal.valueOf(3600000000000), UnitGroup.FLOW_RATE, R.string.cubic_millimeter_per_hour, R.string.cubic_millimeter_per_hour_short),
FlowRateUnit(MyUnitIDS.cubic_millimeter_per_minute, BigDecimal.valueOf(60000000000), UnitGroup.FLOW_RATE, R.string.cubic_millimeter_per_minute, R.string.cubic_millimeter_per_minute_short),
FlowRateUnit(MyUnitIDS.cubic_millimeter_per_second, BigDecimal.valueOf(1000000000), UnitGroup.FLOW_RATE, R.string.cubic_millimeter_per_second, R.string.cubic_millimeter_per_second_short),
FlowRateUnit(MyUnitIDS.cubic_foot_per_hour, BigDecimal.valueOf(127132.80019736), UnitGroup.FLOW_RATE, R.string.cubic_foot_per_hour, R.string.cubic_foot_per_hour_short),
FlowRateUnit(MyUnitIDS.cubic_foot_per_minute, BigDecimal.valueOf(2118.8800032893), UnitGroup.FLOW_RATE, R.string.cubic_foot_per_minute, R.string.cubic_foot_per_minute_short),
FlowRateUnit(MyUnitIDS.cubic_foot_per_second, BigDecimal.valueOf(35.314666721489), UnitGroup.FLOW_RATE, R.string.cubic_foot_per_second, R.string.cubic_foot_per_second_short),
FlowRateUnit(MyUnitIDS.gallons_per_hour_us, BigDecimal.valueOf(951019.38848933), UnitGroup.FLOW_RATE, R.string.gallon_per_hour_us, R.string.gallon_per_hour_us_short),
FlowRateUnit(MyUnitIDS.gallons_per_minute_us, BigDecimal.valueOf(15850.323141489), UnitGroup.FLOW_RATE, R.string.gallon_per_minute_us, R.string.gallon_per_minute_us_short),
FlowRateUnit(MyUnitIDS.gallons_per_second_us, BigDecimal.valueOf(264.17205235815), UnitGroup.FLOW_RATE, R.string.gallon_per_second_us, R.string.gallon_per_second_us_short),
FlowRateUnit(MyUnitIDS.gallons_per_hour_imperial, BigDecimal.valueOf(791889.29387672), UnitGroup.FLOW_RATE, R.string.gallon_per_hour_imperial, R.string.gallon_per_hour_imperial_short),
FlowRateUnit(MyUnitIDS.gallons_per_minute_imperial, BigDecimal.valueOf(13198.154897945), UnitGroup.FLOW_RATE, R.string.gallon_per_minute_imperial, R.string.gallon_per_minute_imperial_short),
FlowRateUnit(MyUnitIDS.gallons_per_second_imperial, BigDecimal.valueOf(219.96924829909), UnitGroup.FLOW_RATE, R.string.gallon_per_second_imperial, R.string.gallon_per_second_imperial_short),
ReverseUnit(MyUnitIDS.liter_per_hour, BigDecimal.valueOf(3600000), UnitGroup.FLOW_RATE, R.string.liter_per_hour, R.string.liter_per_hour_short),
ReverseUnit(MyUnitIDS.liter_per_minute, BigDecimal.valueOf(60000), UnitGroup.FLOW_RATE, R.string.liter_per_minute, R.string.liter_per_minute_short),
ReverseUnit(MyUnitIDS.liter_per_second, BigDecimal.valueOf(1000), UnitGroup.FLOW_RATE, R.string.liter_per_second, R.string.liter_per_second_short),
ReverseUnit(MyUnitIDS.milliliter_per_hour, BigDecimal.valueOf(3600000000), UnitGroup.FLOW_RATE, R.string.milliliter_per_hour, R.string.milliliter_per_hour_short),
ReverseUnit(MyUnitIDS.milliliter_per_minute, BigDecimal.valueOf(60000000), UnitGroup.FLOW_RATE, R.string.milliliter_per_minute, R.string.milliliter_per_minute_short),
ReverseUnit(MyUnitIDS.milliliter_per_second, BigDecimal.valueOf(1000000), UnitGroup.FLOW_RATE, R.string.milliliter_per_second, R.string.milliliter_per_second_short),
ReverseUnit(MyUnitIDS.cubic_meter_per_hour, BigDecimal.valueOf(3600), UnitGroup.FLOW_RATE, R.string.cubic_meter_per_hour, R.string.cubic_meter_per_hour_short),
ReverseUnit(MyUnitIDS.cubic_meter_per_minute, BigDecimal.valueOf(60), UnitGroup.FLOW_RATE, R.string.cubic_meter_per_minute, R.string.cubic_meter_per_minute_short),
ReverseUnit(MyUnitIDS.cubic_meter_per_second, BigDecimal.valueOf(1), UnitGroup.FLOW_RATE, R.string.cubic_meter_per_second, R.string.cubic_meter_per_second_short),
ReverseUnit(MyUnitIDS.cubic_millimeter_per_hour, BigDecimal.valueOf(3600000000000), UnitGroup.FLOW_RATE, R.string.cubic_millimeter_per_hour, R.string.cubic_millimeter_per_hour_short),
ReverseUnit(MyUnitIDS.cubic_millimeter_per_minute, BigDecimal.valueOf(60000000000), UnitGroup.FLOW_RATE, R.string.cubic_millimeter_per_minute, R.string.cubic_millimeter_per_minute_short),
ReverseUnit(MyUnitIDS.cubic_millimeter_per_second, BigDecimal.valueOf(1000000000), UnitGroup.FLOW_RATE, R.string.cubic_millimeter_per_second, R.string.cubic_millimeter_per_second_short),
ReverseUnit(MyUnitIDS.cubic_foot_per_hour, BigDecimal.valueOf(127132.80019736), UnitGroup.FLOW_RATE, R.string.cubic_foot_per_hour, R.string.cubic_foot_per_hour_short),
ReverseUnit(MyUnitIDS.cubic_foot_per_minute, BigDecimal.valueOf(2118.8800032893), UnitGroup.FLOW_RATE, R.string.cubic_foot_per_minute, R.string.cubic_foot_per_minute_short),
ReverseUnit(MyUnitIDS.cubic_foot_per_second, BigDecimal.valueOf(35.314666721489), UnitGroup.FLOW_RATE, R.string.cubic_foot_per_second, R.string.cubic_foot_per_second_short),
ReverseUnit(MyUnitIDS.gallons_per_hour_us, BigDecimal.valueOf(951019.38848933), UnitGroup.FLOW_RATE, R.string.gallon_per_hour_us, R.string.gallon_per_hour_us_short),
ReverseUnit(MyUnitIDS.gallons_per_minute_us, BigDecimal.valueOf(15850.323141489), UnitGroup.FLOW_RATE, R.string.gallon_per_minute_us, R.string.gallon_per_minute_us_short),
ReverseUnit(MyUnitIDS.gallons_per_second_us, BigDecimal.valueOf(264.17205235815), UnitGroup.FLOW_RATE, R.string.gallon_per_second_us, R.string.gallon_per_second_us_short),
ReverseUnit(MyUnitIDS.gallons_per_hour_imperial, BigDecimal.valueOf(791889.29387672), UnitGroup.FLOW_RATE, R.string.gallon_per_hour_imperial, R.string.gallon_per_hour_imperial_short),
ReverseUnit(MyUnitIDS.gallons_per_minute_imperial, BigDecimal.valueOf(13198.154897945), UnitGroup.FLOW_RATE, R.string.gallon_per_minute_imperial, R.string.gallon_per_minute_imperial_short),
ReverseUnit(MyUnitIDS.gallons_per_second_imperial, BigDecimal.valueOf(219.96924829909), UnitGroup.FLOW_RATE, R.string.gallon_per_second_imperial, R.string.gallon_per_second_imperial_short),
)
}

View File

@ -19,20 +19,20 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val fluxCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.maxwell, BigDecimal.valueOf(1), UnitGroup.FLUX, R.string.maxwell, R.string.maxwell_short),
DefaultUnit(MyUnitIDS.microweber, BigDecimal.valueOf(100), UnitGroup.FLUX, R.string.microweber, R.string.microweber_short),
DefaultUnit(MyUnitIDS.milliweber, BigDecimal.valueOf(100000), UnitGroup.FLUX, R.string.milliweber, R.string.milliweber_short),
DefaultUnit(MyUnitIDS.weber, BigDecimal.valueOf(100000000), UnitGroup.FLUX, R.string.weber, R.string.weber_short),
DefaultUnit(MyUnitIDS.kiloweber, BigDecimal.valueOf(100000000000), UnitGroup.FLUX, R.string.kiloweber, R.string.kiloweber_short),
DefaultUnit(MyUnitIDS.megaweber, BigDecimal.valueOf(100000000000000), UnitGroup.FLUX, R.string.megaweber, R.string.megaweber_short),
DefaultUnit(MyUnitIDS.gigaweber, BigDecimal.valueOf(100000000000000000), UnitGroup.FLUX, R.string.gigaweber, R.string.gigaweber_short),
NormalUnit(MyUnitIDS.maxwell, BigDecimal.valueOf(1), UnitGroup.FLUX, R.string.maxwell, R.string.maxwell_short),
NormalUnit(MyUnitIDS.microweber, BigDecimal.valueOf(100), UnitGroup.FLUX, R.string.microweber, R.string.microweber_short),
NormalUnit(MyUnitIDS.milliweber, BigDecimal.valueOf(100000), UnitGroup.FLUX, R.string.milliweber, R.string.milliweber_short),
NormalUnit(MyUnitIDS.weber, BigDecimal.valueOf(100000000), UnitGroup.FLUX, R.string.weber, R.string.weber_short),
NormalUnit(MyUnitIDS.kiloweber, BigDecimal.valueOf(100000000000), UnitGroup.FLUX, R.string.kiloweber, R.string.kiloweber_short),
NormalUnit(MyUnitIDS.megaweber, BigDecimal.valueOf(100000000000000), UnitGroup.FLUX, R.string.megaweber, R.string.megaweber_short),
NormalUnit(MyUnitIDS.gigaweber, BigDecimal.valueOf(100000000000000000), UnitGroup.FLUX, R.string.gigaweber, R.string.gigaweber_short),
)
}
}

View File

@ -19,28 +19,28 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
val forceCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.attonewton, BigDecimal.valueOf(1), UnitGroup.FORCE, R.string.attonewton, R.string.attonewton_short),
DefaultUnit(MyUnitIDS.dyne, BigDecimal.valueOf(1E+13), UnitGroup.FORCE, R.string.dyne, R.string.dyne_short),
DefaultUnit(MyUnitIDS.millinewton, BigDecimal.valueOf(1E+15), UnitGroup.FORCE, R.string.millinewton, R.string.millinewton_short),
DefaultUnit(MyUnitIDS.joule_per_centimeter, BigDecimal.valueOf(1E+16), UnitGroup.FORCE, R.string.joule_per_centimeter, R.string.joule_per_centimeter_short),
DefaultUnit(MyUnitIDS.newton, BigDecimal.valueOf(1E+18), UnitGroup.FORCE, R.string.newton, R.string.newton_short),
DefaultUnit(MyUnitIDS.joule_per_meter, BigDecimal.valueOf(1E+18), UnitGroup.FORCE, R.string.joule_per_meter, R.string.joule_per_meter_short),
DefaultUnit(MyUnitIDS.kilonewton, BigDecimal.valueOf(1E+21), UnitGroup.FORCE, R.string.kilonewton, R.string.kilonewton_short),
DefaultUnit(MyUnitIDS.gram_force, BigDecimal.valueOf(9.80665E+15), UnitGroup.FORCE, R.string.gram_force, R.string.gram_force_short),
DefaultUnit(MyUnitIDS.kilogram_force, BigDecimal.valueOf(9.80665E+18), UnitGroup.FORCE, R.string.kilogram_force, R.string.kilogram_force_short),
DefaultUnit(MyUnitIDS.ton_force, BigDecimal.valueOf(9.80665E+21), UnitGroup.FORCE, R.string.ton_force, R.string.ton_force_short),
DefaultUnit(MyUnitIDS.ounce_force, BigDecimal.valueOf(2.78013850953423008E17), UnitGroup.FORCE, R.string.ounce_force, R.string.ounce_force_short),
DefaultUnit(MyUnitIDS.pound_force, BigDecimal.valueOf(4.4482216152550001E18), UnitGroup.FORCE, R.string.pound_force, R.string.pound_force_short),
DefaultUnit(MyUnitIDS.kilopound_force, BigDecimal.valueOf(4.448221615255E+21), UnitGroup.FORCE, R.string.kilopound_force, R.string.kilopound_force_short),
DefaultUnit(MyUnitIDS.pond, BigDecimal.valueOf(9.80665E+15), UnitGroup.FORCE, R.string.pond, R.string.pond_short),
DefaultUnit(MyUnitIDS.kilopond, BigDecimal.valueOf(9.80665E+18), UnitGroup.FORCE, R.string.kilopond, R.string.kilopond_short),
NormalUnit(MyUnitIDS.attonewton, BigDecimal.valueOf(1), UnitGroup.FORCE, R.string.attonewton, R.string.attonewton_short),
NormalUnit(MyUnitIDS.dyne, BigDecimal.valueOf(1E+13), UnitGroup.FORCE, R.string.dyne, R.string.dyne_short),
NormalUnit(MyUnitIDS.millinewton, BigDecimal.valueOf(1E+15), UnitGroup.FORCE, R.string.millinewton, R.string.millinewton_short),
NormalUnit(MyUnitIDS.joule_per_centimeter, BigDecimal.valueOf(1E+16), UnitGroup.FORCE, R.string.joule_per_centimeter, R.string.joule_per_centimeter_short),
NormalUnit(MyUnitIDS.newton, BigDecimal.valueOf(1E+18), UnitGroup.FORCE, R.string.newton, R.string.newton_short),
NormalUnit(MyUnitIDS.joule_per_meter, BigDecimal.valueOf(1E+18), UnitGroup.FORCE, R.string.joule_per_meter, R.string.joule_per_meter_short),
NormalUnit(MyUnitIDS.kilonewton, BigDecimal.valueOf(1E+21), UnitGroup.FORCE, R.string.kilonewton, R.string.kilonewton_short),
NormalUnit(MyUnitIDS.gram_force, BigDecimal.valueOf(9.80665E+15), UnitGroup.FORCE, R.string.gram_force, R.string.gram_force_short),
NormalUnit(MyUnitIDS.kilogram_force, BigDecimal.valueOf(9.80665E+18), UnitGroup.FORCE, R.string.kilogram_force, R.string.kilogram_force_short),
NormalUnit(MyUnitIDS.ton_force, BigDecimal.valueOf(9.80665E+21), UnitGroup.FORCE, R.string.ton_force, R.string.ton_force_short),
NormalUnit(MyUnitIDS.ounce_force, BigDecimal.valueOf(2.78013850953423008E17), UnitGroup.FORCE, R.string.ounce_force, R.string.ounce_force_short),
NormalUnit(MyUnitIDS.pound_force, BigDecimal.valueOf(4.4482216152550001E18), UnitGroup.FORCE, R.string.pound_force, R.string.pound_force_short),
NormalUnit(MyUnitIDS.kilopound_force, BigDecimal.valueOf(4.448221615255E+21), UnitGroup.FORCE, R.string.kilopound_force, R.string.kilopound_force_short),
NormalUnit(MyUnitIDS.pond, BigDecimal.valueOf(9.80665E+15), UnitGroup.FORCE, R.string.pond, R.string.pond_short),
NormalUnit(MyUnitIDS.kilopond, BigDecimal.valueOf(9.80665E+18), UnitGroup.FORCE, R.string.kilopond, R.string.kilopond_short),
)
}

View File

@ -19,39 +19,39 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val lengthCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.attometer, BigDecimal.valueOf(1.0), UnitGroup.LENGTH, R.string.attometer, R.string.attometer_short),
DefaultUnit(MyUnitIDS.nanometer, BigDecimal.valueOf(1.0E+9), UnitGroup.LENGTH, R.string.nanometer, R.string.nanometer_short),
DefaultUnit(MyUnitIDS.micrometer, BigDecimal.valueOf(1.0E+12), UnitGroup.LENGTH, R.string.micrometer, R.string.micrometer_short),
DefaultUnit(MyUnitIDS.millimeter, BigDecimal.valueOf(1.0E+15), UnitGroup.LENGTH, R.string.millimeter, R.string.millimeter_short),
DefaultUnit(MyUnitIDS.centimeter, BigDecimal.valueOf(1.0E+16), UnitGroup.LENGTH, R.string.centimeter, R.string.centimeter_short),
DefaultUnit(MyUnitIDS.decimeter, BigDecimal.valueOf(1.0E+17), UnitGroup.LENGTH, R.string.decimeter, R.string.decimeter_short),
DefaultUnit(MyUnitIDS.meter, BigDecimal.valueOf(1.0E+18), UnitGroup.LENGTH, R.string.meter, R.string.meter_short),
DefaultUnit(MyUnitIDS.kilometer, BigDecimal.valueOf(1.0E+21), UnitGroup.LENGTH, R.string.kilometer, R.string.kilometer_short),
DefaultUnit(MyUnitIDS.nautical_mile, BigDecimal.valueOf(1.852E+21), UnitGroup.LENGTH, R.string.nautical_mile, R.string.nautical_mile_short),
DefaultUnit(MyUnitIDS.inch, BigDecimal.valueOf(25_400_000_000_000_000), UnitGroup.LENGTH, R.string.inch, R.string.inch_short),
DefaultUnit(MyUnitIDS.foot, BigDecimal.valueOf(304_800_000_000_002_200), UnitGroup.LENGTH, R.string.foot, R.string.foot_short),
DefaultUnit(MyUnitIDS.yard, BigDecimal.valueOf(914_400_000_000_006_400), UnitGroup.LENGTH, R.string.yard, R.string.yard_short),
DefaultUnit(MyUnitIDS.mile, BigDecimal.valueOf(1_609_344_000_000_010_500_000.0), UnitGroup.LENGTH, R.string.mile, R.string.mile_short),
DefaultUnit(MyUnitIDS.light_year, BigDecimal.valueOf(9.460730472E+33), UnitGroup.LENGTH, R.string.light_year, R.string.light_year_short),
DefaultUnit(MyUnitIDS.parsec, BigDecimal.valueOf(3.08567758149136E+34), UnitGroup.LENGTH, R.string.parsec, R.string.parsec_short),
DefaultUnit(MyUnitIDS.kiloparsec, BigDecimal.valueOf(3.08567758149136E+37), UnitGroup.LENGTH, R.string.kiloparsec, R.string.kiloparsec_short),
DefaultUnit(MyUnitIDS.megaparsec, BigDecimal.valueOf(3.08567758149136E+40), UnitGroup.LENGTH, R.string.megaparsec, R.string.megaparsec_short),
DefaultUnit(MyUnitIDS.mercury_equatorial_radius, BigDecimal.valueOf(2.4397E+24), UnitGroup.LENGTH, R.string.mercury_equatorial_radius, R.string.mercury_equatorial_radius_short),
DefaultUnit(MyUnitIDS.venus_equatorial_radius, BigDecimal.valueOf(6.0518E+24), UnitGroup.LENGTH, R.string.venus_equatorial_radius, R.string.venus_equatorial_radius_short),
DefaultUnit(MyUnitIDS.earth_equatorial_radius, BigDecimal.valueOf(6.371E+24), UnitGroup.LENGTH, R.string.earth_equatorial_radius, R.string.earth_equatorial_radius_short),
DefaultUnit(MyUnitIDS.mars_equatorial_radius, BigDecimal.valueOf(3.3895E+24), UnitGroup.LENGTH, R.string.mars_equatorial_radius, R.string.mars_equatorial_radius_short),
DefaultUnit(MyUnitIDS.jupiter_equatorial_radius, BigDecimal.valueOf(6.9911E+25), UnitGroup.LENGTH, R.string.jupiter_equatorial_radius, R.string.jupiter_equatorial_radius_short),
DefaultUnit(MyUnitIDS.saturn_equatorial_radius, BigDecimal.valueOf(5.8232E+25), UnitGroup.LENGTH, R.string.saturn_equatorial_radius, R.string.saturn_equatorial_radius_short),
DefaultUnit(MyUnitIDS.uranus_equatorial_radius, BigDecimal.valueOf(2.5362E+25), UnitGroup.LENGTH, R.string.uranus_equatorial_radius, R.string.uranus_equatorial_radius_short),
DefaultUnit(MyUnitIDS.neptune_equatorial_radius, BigDecimal.valueOf(2.4622E+25), UnitGroup.LENGTH, R.string.neptune_equatorial_radius, R.string.neptune_equatorial_radius_short),
DefaultUnit(MyUnitIDS.sun_equatorial_radius, BigDecimal.valueOf(6.95508E+26), UnitGroup.LENGTH, R.string.sun_equatorial_radius, R.string.sun_equatorial_radius_short),
NormalUnit(MyUnitIDS.attometer, BigDecimal.valueOf(1.0), UnitGroup.LENGTH, R.string.attometer, R.string.attometer_short),
NormalUnit(MyUnitIDS.nanometer, BigDecimal.valueOf(1.0E+9), UnitGroup.LENGTH, R.string.nanometer, R.string.nanometer_short),
NormalUnit(MyUnitIDS.micrometer, BigDecimal.valueOf(1.0E+12), UnitGroup.LENGTH, R.string.micrometer, R.string.micrometer_short),
NormalUnit(MyUnitIDS.millimeter, BigDecimal.valueOf(1.0E+15), UnitGroup.LENGTH, R.string.millimeter, R.string.millimeter_short),
NormalUnit(MyUnitIDS.centimeter, BigDecimal.valueOf(1.0E+16), UnitGroup.LENGTH, R.string.centimeter, R.string.centimeter_short),
NormalUnit(MyUnitIDS.decimeter, BigDecimal.valueOf(1.0E+17), UnitGroup.LENGTH, R.string.decimeter, R.string.decimeter_short),
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),
NormalUnit(MyUnitIDS.light_year, BigDecimal.valueOf(9.460730472E+33), UnitGroup.LENGTH, R.string.light_year, R.string.light_year_short),
NormalUnit(MyUnitIDS.parsec, BigDecimal.valueOf(3.08567758149136E+34), UnitGroup.LENGTH, R.string.parsec, R.string.parsec_short),
NormalUnit(MyUnitIDS.kiloparsec, BigDecimal.valueOf(3.08567758149136E+37), UnitGroup.LENGTH, R.string.kiloparsec, R.string.kiloparsec_short),
NormalUnit(MyUnitIDS.megaparsec, BigDecimal.valueOf(3.08567758149136E+40), UnitGroup.LENGTH, R.string.megaparsec, R.string.megaparsec_short),
NormalUnit(MyUnitIDS.mercury_equatorial_radius, BigDecimal.valueOf(2.4397E+24), UnitGroup.LENGTH, R.string.mercury_equatorial_radius, R.string.mercury_equatorial_radius_short),
NormalUnit(MyUnitIDS.venus_equatorial_radius, BigDecimal.valueOf(6.0518E+24), UnitGroup.LENGTH, R.string.venus_equatorial_radius, R.string.venus_equatorial_radius_short),
NormalUnit(MyUnitIDS.earth_equatorial_radius, BigDecimal.valueOf(6.371E+24), UnitGroup.LENGTH, R.string.earth_equatorial_radius, R.string.earth_equatorial_radius_short),
NormalUnit(MyUnitIDS.mars_equatorial_radius, BigDecimal.valueOf(3.3895E+24), UnitGroup.LENGTH, R.string.mars_equatorial_radius, R.string.mars_equatorial_radius_short),
NormalUnit(MyUnitIDS.jupiter_equatorial_radius, BigDecimal.valueOf(6.9911E+25), UnitGroup.LENGTH, R.string.jupiter_equatorial_radius, R.string.jupiter_equatorial_radius_short),
NormalUnit(MyUnitIDS.saturn_equatorial_radius, BigDecimal.valueOf(5.8232E+25), UnitGroup.LENGTH, R.string.saturn_equatorial_radius, R.string.saturn_equatorial_radius_short),
NormalUnit(MyUnitIDS.uranus_equatorial_radius, BigDecimal.valueOf(2.5362E+25), UnitGroup.LENGTH, R.string.uranus_equatorial_radius, R.string.uranus_equatorial_radius_short),
NormalUnit(MyUnitIDS.neptune_equatorial_radius, BigDecimal.valueOf(2.4622E+25), UnitGroup.LENGTH, R.string.neptune_equatorial_radius, R.string.neptune_equatorial_radius_short),
NormalUnit(MyUnitIDS.sun_equatorial_radius, BigDecimal.valueOf(6.95508E+26), UnitGroup.LENGTH, R.string.sun_equatorial_radius, R.string.sun_equatorial_radius_short),
)
}
}

View File

@ -19,32 +19,32 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
val luminanceCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.candela_per_square_meter, BigDecimal.valueOf(31415926.5359), UnitGroup.LUMINANCE, R.string.candela_per_square_meter, R.string.candela_per_square_meter_short),
DefaultUnit(MyUnitIDS.candela_per_square_centimeter, BigDecimal.valueOf(314159265359), UnitGroup.LUMINANCE, R.string.candela_per_square_centimeter, R.string.candela_per_square_centimeter_short),
DefaultUnit(MyUnitIDS.candela_per_square_foot, BigDecimal.valueOf(338158218.89), UnitGroup.LUMINANCE, R.string.candela_per_square_foot, R.string.candela_per_square_foot_short),
DefaultUnit(MyUnitIDS.candela_per_square_inch, BigDecimal.valueOf(48694783520), UnitGroup.LUMINANCE, R.string.candela_per_square_inch, R.string.candela_per_square_inch_short),
DefaultUnit(MyUnitIDS.kilocandela_per_square_meter, BigDecimal.valueOf(31415926535.9), UnitGroup.LUMINANCE, R.string.kilocandela_per_square_meter, R.string.kilocandela_per_square_meter_short),
DefaultUnit(MyUnitIDS.stilb, BigDecimal.valueOf(314159265359), UnitGroup.LUMINANCE, R.string.stilb, R.string.stilb_short),
DefaultUnit(MyUnitIDS.lumen_per_square_meter_per_steradian, BigDecimal.valueOf(31415926.5359), UnitGroup.LUMINANCE, R.string.lumen_per_square_meter_per_steradian, R.string.lumen_per_square_meter_per_steradian_short),
DefaultUnit(MyUnitIDS.lumen_per_square_centimeter_per_steradian, BigDecimal.valueOf(314159265359), UnitGroup.LUMINANCE, R.string.lumen_per_square_centimeter_per_steradian, R.string.lumen_per_square_centimeter_per_steradian_short),
DefaultUnit(MyUnitIDS.lumen_per_square_foot_per_steradian, BigDecimal.valueOf(338158218.89), UnitGroup.LUMINANCE, R.string.lumen_per_square_foot_per_steradian, R.string.lumen_per_square_foot_per_steradian_short),
DefaultUnit(MyUnitIDS.watt_per_square_centimeter_per_steradian, BigDecimal.valueOf(214570778240185), UnitGroup.LUMINANCE, R.string.watt_per_square_centimeter_per_steradian, R.string.watt_per_square_centimeter_per_steradian_short),
DefaultUnit(MyUnitIDS.nit, BigDecimal.valueOf(31415926.5359), UnitGroup.LUMINANCE, R.string.nit, R.string.nit_short),
DefaultUnit(MyUnitIDS.millinit, BigDecimal.valueOf(31415.9265359), UnitGroup.LUMINANCE, R.string.millinit, R.string.millinit_short),
DefaultUnit(MyUnitIDS.lambert, BigDecimal.valueOf(100000000000), UnitGroup.LUMINANCE, R.string.lambert, R.string.lambert_short),
DefaultUnit(MyUnitIDS.millilambert, BigDecimal.valueOf(100000000), UnitGroup.LUMINANCE, R.string.millilambert, R.string.millilambert_short),
DefaultUnit(MyUnitIDS.foot_lambert, BigDecimal.valueOf(107639104.167), UnitGroup.LUMINANCE, R.string.foot_lambert, R.string.foot_lambert_short),
DefaultUnit(MyUnitIDS.apostilb, BigDecimal.valueOf(10000000), UnitGroup.LUMINANCE, R.string.apostilb, R.string.apostilb_short),
DefaultUnit(MyUnitIDS.blondel, BigDecimal.valueOf(10000000), UnitGroup.LUMINANCE, R.string.blondel, R.string.blondel_short),
DefaultUnit(MyUnitIDS.skot, BigDecimal.valueOf(10000), UnitGroup.LUMINANCE, R.string.skot, R.string.skot_short),
DefaultUnit(MyUnitIDS.bril, BigDecimal.valueOf(1), UnitGroup.LUMINANCE, R.string.bril, R.string.bril_short),
NormalUnit(MyUnitIDS.candela_per_square_meter, BigDecimal.valueOf(31415926.5359), UnitGroup.LUMINANCE, R.string.candela_per_square_meter, R.string.candela_per_square_meter_short),
NormalUnit(MyUnitIDS.candela_per_square_centimeter, BigDecimal.valueOf(314159265359), UnitGroup.LUMINANCE, R.string.candela_per_square_centimeter, R.string.candela_per_square_centimeter_short),
NormalUnit(MyUnitIDS.candela_per_square_foot, BigDecimal.valueOf(338158218.89), UnitGroup.LUMINANCE, R.string.candela_per_square_foot, R.string.candela_per_square_foot_short),
NormalUnit(MyUnitIDS.candela_per_square_inch, BigDecimal.valueOf(48694783520), UnitGroup.LUMINANCE, R.string.candela_per_square_inch, R.string.candela_per_square_inch_short),
NormalUnit(MyUnitIDS.kilocandela_per_square_meter, BigDecimal.valueOf(31415926535.9), UnitGroup.LUMINANCE, R.string.kilocandela_per_square_meter, R.string.kilocandela_per_square_meter_short),
NormalUnit(MyUnitIDS.stilb, BigDecimal.valueOf(314159265359), UnitGroup.LUMINANCE, R.string.stilb, R.string.stilb_short),
NormalUnit(MyUnitIDS.lumen_per_square_meter_per_steradian, BigDecimal.valueOf(31415926.5359), UnitGroup.LUMINANCE, R.string.lumen_per_square_meter_per_steradian, R.string.lumen_per_square_meter_per_steradian_short),
NormalUnit(MyUnitIDS.lumen_per_square_centimeter_per_steradian, BigDecimal.valueOf(314159265359), UnitGroup.LUMINANCE, R.string.lumen_per_square_centimeter_per_steradian, R.string.lumen_per_square_centimeter_per_steradian_short),
NormalUnit(MyUnitIDS.lumen_per_square_foot_per_steradian, BigDecimal.valueOf(338158218.89), UnitGroup.LUMINANCE, R.string.lumen_per_square_foot_per_steradian, R.string.lumen_per_square_foot_per_steradian_short),
NormalUnit(MyUnitIDS.watt_per_square_centimeter_per_steradian, BigDecimal.valueOf(214570778240185), UnitGroup.LUMINANCE, R.string.watt_per_square_centimeter_per_steradian, R.string.watt_per_square_centimeter_per_steradian_short),
NormalUnit(MyUnitIDS.nit, BigDecimal.valueOf(31415926.5359), UnitGroup.LUMINANCE, R.string.nit, R.string.nit_short),
NormalUnit(MyUnitIDS.millinit, BigDecimal.valueOf(31415.9265359), UnitGroup.LUMINANCE, R.string.millinit, R.string.millinit_short),
NormalUnit(MyUnitIDS.lambert, BigDecimal.valueOf(100000000000), UnitGroup.LUMINANCE, R.string.lambert, R.string.lambert_short),
NormalUnit(MyUnitIDS.millilambert, BigDecimal.valueOf(100000000), UnitGroup.LUMINANCE, R.string.millilambert, R.string.millilambert_short),
NormalUnit(MyUnitIDS.foot_lambert, BigDecimal.valueOf(107639104.167), UnitGroup.LUMINANCE, R.string.foot_lambert, R.string.foot_lambert_short),
NormalUnit(MyUnitIDS.apostilb, BigDecimal.valueOf(10000000), UnitGroup.LUMINANCE, R.string.apostilb, R.string.apostilb_short),
NormalUnit(MyUnitIDS.blondel, BigDecimal.valueOf(10000000), UnitGroup.LUMINANCE, R.string.blondel, R.string.blondel_short),
NormalUnit(MyUnitIDS.skot, BigDecimal.valueOf(10000), UnitGroup.LUMINANCE, R.string.skot, R.string.skot_short),
NormalUnit(MyUnitIDS.bril, BigDecimal.valueOf(1), UnitGroup.LUMINANCE, R.string.bril, R.string.bril_short),
)
}

View File

@ -19,33 +19,33 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val massCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.electron_mass_rest, BigDecimal.valueOf(9.1093897E-28), UnitGroup.MASS, R.string.electron_mass_rest, R.string.electron_mass_rest_short),
DefaultUnit(MyUnitIDS.atomic_mass_unit, BigDecimal.valueOf(1.6605402E-24), UnitGroup.MASS, R.string.atomic_mass_unit, R.string.atomic_mass_unit_short),
DefaultUnit(MyUnitIDS.microgram, BigDecimal(1E-6), UnitGroup.MASS, R.string.microgram, R.string.microgram_short),
DefaultUnit(MyUnitIDS.milligram, BigDecimal.valueOf(1E-3), UnitGroup.MASS, R.string.milligram, R.string.milligram_short),
DefaultUnit(MyUnitIDS.gram, BigDecimal.valueOf(1), UnitGroup.MASS, R.string.gram, R.string.gram_short),
DefaultUnit(MyUnitIDS.kilogram, BigDecimal.valueOf(1E+3), UnitGroup.MASS, R.string.kilogram, R.string.kilogram_short),
DefaultUnit(MyUnitIDS.metric_ton, BigDecimal.valueOf(1E+6), UnitGroup.MASS, R.string.metric_ton, R.string.metric_ton_short),
DefaultUnit(MyUnitIDS.imperial_ton, BigDecimal.valueOf(1016046.9088), UnitGroup.MASS, R.string.imperial_ton, R.string.imperial_ton_short),
DefaultUnit(MyUnitIDS.ounce, BigDecimal.valueOf(28.349523125), UnitGroup.MASS, R.string.ounce, R.string.ounce_short),
DefaultUnit(MyUnitIDS.carat, BigDecimal.valueOf(0.2), UnitGroup.MASS, R.string.carat, R.string.carat_short),
DefaultUnit(MyUnitIDS.pound, BigDecimal.valueOf(453.59237), UnitGroup.MASS, R.string.pound, R.string.pound_short),
DefaultUnit(MyUnitIDS.mercury_mass, BigDecimal.valueOf(3.30104E+26), UnitGroup.MASS, R.string.mercury_mass, R.string.mercury_mass_short),
DefaultUnit(MyUnitIDS.venus_mass, BigDecimal.valueOf(4.86732E+27), UnitGroup.MASS, R.string.venus_mass, R.string.venus_mass_short),
DefaultUnit(MyUnitIDS.earth_mass, BigDecimal.valueOf(5.97219E+27), UnitGroup.MASS, R.string.earth_mass, R.string.earth_mass_short),
DefaultUnit(MyUnitIDS.mars_mass, BigDecimal.valueOf(6.41693E+26), UnitGroup.MASS, R.string.mars_mass, R.string.mars_mass_short),
DefaultUnit(MyUnitIDS.jupiter_mass, BigDecimal.valueOf(1.89813E+30), UnitGroup.MASS, R.string.jupiter_mass, R.string.jupiter_mass_short),
DefaultUnit(MyUnitIDS.saturn_mass, BigDecimal.valueOf(5.68319E+29), UnitGroup.MASS, R.string.saturn_mass, R.string.saturn_mass_short),
DefaultUnit(MyUnitIDS.uranus_mass, BigDecimal.valueOf(8.68103E+28), UnitGroup.MASS, R.string.uranus_mass, R.string.uranus_mass_short),
DefaultUnit(MyUnitIDS.neptune_mass, BigDecimal.valueOf(1.0241E+29), UnitGroup.MASS, R.string.neptune_mass, R.string.neptune_mass_short),
DefaultUnit(MyUnitIDS.sun_mass, BigDecimal.valueOf(1.9891E+33), UnitGroup.MASS, R.string.sun_mass, R.string.sun_mass_short),
NormalUnit(MyUnitIDS.electron_mass_rest, BigDecimal.valueOf(9.1093897E-28), UnitGroup.MASS, R.string.electron_mass_rest, R.string.electron_mass_rest_short),
NormalUnit(MyUnitIDS.atomic_mass_unit, BigDecimal.valueOf(1.6605402E-24), UnitGroup.MASS, R.string.atomic_mass_unit, R.string.atomic_mass_unit_short),
NormalUnit(MyUnitIDS.microgram, BigDecimal(1E-6), UnitGroup.MASS, R.string.microgram, R.string.microgram_short),
NormalUnit(MyUnitIDS.milligram, BigDecimal.valueOf(1E-3), UnitGroup.MASS, R.string.milligram, R.string.milligram_short),
NormalUnit(MyUnitIDS.gram, BigDecimal.valueOf(1), UnitGroup.MASS, R.string.gram, R.string.gram_short),
NormalUnit(MyUnitIDS.kilogram, BigDecimal.valueOf(1E+3), UnitGroup.MASS, R.string.kilogram, R.string.kilogram_short),
NormalUnit(MyUnitIDS.metric_ton, BigDecimal.valueOf(1E+6), UnitGroup.MASS, R.string.metric_ton, R.string.metric_ton_short),
NormalUnit(MyUnitIDS.imperial_ton, BigDecimal.valueOf(1016046.9088), UnitGroup.MASS, R.string.imperial_ton, R.string.imperial_ton_short),
NormalUnit(MyUnitIDS.ounce, BigDecimal.valueOf(28.349523125), UnitGroup.MASS, R.string.ounce, R.string.ounce_short),
NormalUnit(MyUnitIDS.carat, BigDecimal.valueOf(0.2), UnitGroup.MASS, R.string.carat, R.string.carat_short),
NormalUnit(MyUnitIDS.pound, BigDecimal.valueOf(453.59237), UnitGroup.MASS, R.string.pound, R.string.pound_short),
NormalUnit(MyUnitIDS.mercury_mass, BigDecimal.valueOf(3.30104E+26), UnitGroup.MASS, R.string.mercury_mass, R.string.mercury_mass_short),
NormalUnit(MyUnitIDS.venus_mass, BigDecimal.valueOf(4.86732E+27), UnitGroup.MASS, R.string.venus_mass, R.string.venus_mass_short),
NormalUnit(MyUnitIDS.earth_mass, BigDecimal.valueOf(5.97219E+27), UnitGroup.MASS, R.string.earth_mass, R.string.earth_mass_short),
NormalUnit(MyUnitIDS.mars_mass, BigDecimal.valueOf(6.41693E+26), UnitGroup.MASS, R.string.mars_mass, R.string.mars_mass_short),
NormalUnit(MyUnitIDS.jupiter_mass, BigDecimal.valueOf(1.89813E+30), UnitGroup.MASS, R.string.jupiter_mass, R.string.jupiter_mass_short),
NormalUnit(MyUnitIDS.saturn_mass, BigDecimal.valueOf(5.68319E+29), UnitGroup.MASS, R.string.saturn_mass, R.string.saturn_mass_short),
NormalUnit(MyUnitIDS.uranus_mass, BigDecimal.valueOf(8.68103E+28), UnitGroup.MASS, R.string.uranus_mass, R.string.uranus_mass_short),
NormalUnit(MyUnitIDS.neptune_mass, BigDecimal.valueOf(1.0241E+29), UnitGroup.MASS, R.string.neptune_mass, R.string.neptune_mass_short),
NormalUnit(MyUnitIDS.sun_mass, BigDecimal.valueOf(1.9891E+33), UnitGroup.MASS, R.string.sun_mass, R.string.sun_mass_short),
)
}
}

View File

@ -19,27 +19,28 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.NumberBaseUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NumberBaseUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val numberBaseCollection: List<AbstractUnit> by lazy {
listOf(
NumberBaseUnit(MyUnitIDS.binary, 2, UnitGroup.NUMBER_BASE, R.string.binary, R.string.binary_short),
NumberBaseUnit(MyUnitIDS.ternary, 3, UnitGroup.NUMBER_BASE, R.string.ternary, R.string.ternary_short),
NumberBaseUnit(MyUnitIDS.quaternary, 4, UnitGroup.NUMBER_BASE, R.string.quaternary, R.string.quaternary_short),
NumberBaseUnit(MyUnitIDS.quinary, 5, UnitGroup.NUMBER_BASE, R.string.quinary, R.string.quinary_short),
NumberBaseUnit(MyUnitIDS.senary, 6, UnitGroup.NUMBER_BASE, R.string.senary, R.string.senary_short),
NumberBaseUnit(MyUnitIDS.septenary, 7, UnitGroup.NUMBER_BASE, R.string.septenary, R.string.septenary_short),
NumberBaseUnit(MyUnitIDS.octal, 8, UnitGroup.NUMBER_BASE, R.string.octal, R.string.octal_short),
NumberBaseUnit(MyUnitIDS.nonary, 9, UnitGroup.NUMBER_BASE, R.string.nonary, R.string.nonary_short),
NumberBaseUnit(MyUnitIDS.decimal, 10, UnitGroup.NUMBER_BASE, R.string.decimal, R.string.decimal_short),
NumberBaseUnit(MyUnitIDS.undecimal, 11, UnitGroup.NUMBER_BASE, R.string.undecimal, R.string.undecimal_short),
NumberBaseUnit(MyUnitIDS.duodecimal, 12, UnitGroup.NUMBER_BASE, R.string.duodecimal, R.string.duodecimal_short),
NumberBaseUnit(MyUnitIDS.tridecimal, 13, UnitGroup.NUMBER_BASE, R.string.tridecimal, R.string.tridecimal_short),
NumberBaseUnit(MyUnitIDS.tetradecimal, 14, UnitGroup.NUMBER_BASE, R.string.tetradecimal, R.string.tetradecimal_short),
NumberBaseUnit(MyUnitIDS.pentadecimal, 15, UnitGroup.NUMBER_BASE, R.string.pentadecimal, R.string.pentadecimal_short),
NumberBaseUnit(MyUnitIDS.hexadecimal, 16, UnitGroup.NUMBER_BASE, R.string.hexadecimal, R.string.hexadecimal_short),
NumberBaseUnit(MyUnitIDS.binary, BigDecimal.valueOf(2.0), UnitGroup.NUMBER_BASE, R.string.binary, R.string.binary_short),
NumberBaseUnit(MyUnitIDS.ternary, BigDecimal.valueOf(3.0), UnitGroup.NUMBER_BASE, R.string.ternary, R.string.ternary_short),
NumberBaseUnit(MyUnitIDS.quaternary, BigDecimal.valueOf(4.0), UnitGroup.NUMBER_BASE, R.string.quaternary, R.string.quaternary_short),
NumberBaseUnit(MyUnitIDS.quinary, BigDecimal.valueOf(5.0), UnitGroup.NUMBER_BASE, R.string.quinary, R.string.quinary_short),
NumberBaseUnit(MyUnitIDS.senary, BigDecimal.valueOf(6.0), UnitGroup.NUMBER_BASE, R.string.senary, R.string.senary_short),
NumberBaseUnit(MyUnitIDS.septenary, BigDecimal.valueOf(7.0), UnitGroup.NUMBER_BASE, R.string.septenary, R.string.septenary_short),
NumberBaseUnit(MyUnitIDS.octal, BigDecimal.valueOf(8.0), UnitGroup.NUMBER_BASE, R.string.octal, R.string.octal_short),
NumberBaseUnit(MyUnitIDS.nonary, BigDecimal.valueOf(9.0), UnitGroup.NUMBER_BASE, R.string.nonary, R.string.nonary_short),
NumberBaseUnit(MyUnitIDS.decimal, BigDecimal.valueOf(10.0), UnitGroup.NUMBER_BASE, R.string.decimal, R.string.decimal_short),
NumberBaseUnit(MyUnitIDS.undecimal, BigDecimal.valueOf(11.0), UnitGroup.NUMBER_BASE, R.string.undecimal, R.string.undecimal_short),
NumberBaseUnit(MyUnitIDS.duodecimal, BigDecimal.valueOf(12.0), UnitGroup.NUMBER_BASE, R.string.duodecimal, R.string.duodecimal_short),
NumberBaseUnit(MyUnitIDS.tridecimal, BigDecimal.valueOf(13.0), UnitGroup.NUMBER_BASE, R.string.tridecimal, R.string.tridecimal_short),
NumberBaseUnit(MyUnitIDS.tetradecimal, BigDecimal.valueOf(14.0), UnitGroup.NUMBER_BASE, R.string.tetradecimal, R.string.tetradecimal_short),
NumberBaseUnit(MyUnitIDS.pentadecimal, BigDecimal.valueOf(15.0), UnitGroup.NUMBER_BASE, R.string.pentadecimal, R.string.pentadecimal_short),
NumberBaseUnit(MyUnitIDS.hexadecimal, BigDecimal.valueOf(16.0), UnitGroup.NUMBER_BASE, R.string.hexadecimal, R.string.hexadecimal_short),
)
}
}

View File

@ -19,18 +19,18 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val powerCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.attowatt, BigDecimal.valueOf(1), UnitGroup.POWER, R.string.attowatt, R.string.attowatt_short),
DefaultUnit(MyUnitIDS.watt, BigDecimal.valueOf(1_000_000_000_000_000_000), UnitGroup.POWER, R.string.watt, R.string.watt_short),
DefaultUnit(MyUnitIDS.kilowatt, BigDecimal.valueOf(1.0E+21), UnitGroup.POWER, R.string.kilowatt, R.string.kilowatt_short),
DefaultUnit(MyUnitIDS.megawatt, BigDecimal.valueOf(1.0E+24), UnitGroup.POWER, R.string.megawatt, R.string.megawatt_short),
DefaultUnit(MyUnitIDS.horse_power_mechanical, BigDecimal.valueOf(745_699_871_582_285_700_000.0), UnitGroup.POWER, R.string.horse_power_mechanical, R.string.horse_power_mechanical_short),
NormalUnit(MyUnitIDS.attowatt, BigDecimal.valueOf(1), UnitGroup.POWER, R.string.attowatt, R.string.attowatt_short),
NormalUnit(MyUnitIDS.watt, BigDecimal.valueOf(1_000_000_000_000_000_000), UnitGroup.POWER, R.string.watt, R.string.watt_short),
NormalUnit(MyUnitIDS.kilowatt, BigDecimal.valueOf(1.0E+21), UnitGroup.POWER, R.string.kilowatt, R.string.kilowatt_short),
NormalUnit(MyUnitIDS.megawatt, BigDecimal.valueOf(1.0E+24), UnitGroup.POWER, R.string.megawatt, R.string.megawatt_short),
NormalUnit(MyUnitIDS.horse_power_mechanical, BigDecimal.valueOf(745_699_871_582_285_700_000.0), UnitGroup.POWER, R.string.horse_power_mechanical, R.string.horse_power_mechanical_short),
)
}
}

View File

@ -19,38 +19,38 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
val prefixCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.prefix_quetta, BigDecimal.valueOf(1E+30), UnitGroup.PREFIX, R.string.prefix_quetta, R.string.prefix_quetta_short),
DefaultUnit(MyUnitIDS.prefix_ronna, BigDecimal.valueOf(1E+27), UnitGroup.PREFIX, R.string.prefix_ronna, R.string.prefix_ronna_short),
DefaultUnit(MyUnitIDS.prefix_yotta, BigDecimal.valueOf(1E+24), UnitGroup.PREFIX, R.string.prefix_yotta, R.string.prefix_yotta_short),
DefaultUnit(MyUnitIDS.prefix_zetta, BigDecimal.valueOf(1E+21), UnitGroup.PREFIX, R.string.prefix_zetta, R.string.prefix_zetta_short),
DefaultUnit(MyUnitIDS.prefix_exa, BigDecimal.valueOf(1E+18), UnitGroup.PREFIX, R.string.prefix_exa, R.string.prefix_exa_short),
DefaultUnit(MyUnitIDS.prefix_peta, BigDecimal.valueOf(1E+15), UnitGroup.PREFIX, R.string.prefix_peta, R.string.prefix_peta_short),
DefaultUnit(MyUnitIDS.prefix_tera, BigDecimal.valueOf(1E+12), UnitGroup.PREFIX, R.string.prefix_tera, R.string.prefix_tera_short),
DefaultUnit(MyUnitIDS.prefix_giga, BigDecimal.valueOf(1E+9), UnitGroup.PREFIX, R.string.prefix_giga, R.string.prefix_giga_short),
DefaultUnit(MyUnitIDS.prefix_mega, BigDecimal.valueOf(1E+6), UnitGroup.PREFIX, R.string.prefix_mega, R.string.prefix_mega_short),
DefaultUnit(MyUnitIDS.prefix_kilo, BigDecimal.valueOf(1E+3), UnitGroup.PREFIX, R.string.prefix_kilo, R.string.prefix_kilo_short),
DefaultUnit(MyUnitIDS.prefix_hecto, BigDecimal.valueOf(1E+2), UnitGroup.PREFIX, R.string.prefix_hecto, R.string.prefix_hecto_short),
DefaultUnit(MyUnitIDS.prefix_deca, BigDecimal.valueOf(1E+1), UnitGroup.PREFIX, R.string.prefix_deca, R.string.prefix_deca_short),
DefaultUnit(MyUnitIDS.prefix_base, BigDecimal.valueOf(1E+0), UnitGroup.PREFIX, R.string.prefix_base, R.string.prefix_base_short),
DefaultUnit(MyUnitIDS.prefix_deci, BigDecimal.valueOf(1E-1), UnitGroup.PREFIX, R.string.prefix_deci, R.string.prefix_deci_short),
DefaultUnit(MyUnitIDS.prefix_centi, BigDecimal.valueOf(1E-2), UnitGroup.PREFIX, R.string.prefix_centi, R.string.prefix_centi_short),
DefaultUnit(MyUnitIDS.prefix_milli, BigDecimal.valueOf(1E-3), UnitGroup.PREFIX, R.string.prefix_milli, R.string.prefix_milli_short),
DefaultUnit(MyUnitIDS.prefix_micro, BigDecimal.valueOf(1E-6), UnitGroup.PREFIX, R.string.prefix_micro, R.string.prefix_micro_short),
DefaultUnit(MyUnitIDS.prefix_nano, BigDecimal.valueOf(1E-9), UnitGroup.PREFIX, R.string.prefix_nano, R.string.prefix_nano_short),
DefaultUnit(MyUnitIDS.prefix_pico, BigDecimal.valueOf(1E-12), UnitGroup.PREFIX, R.string.prefix_pico, R.string.prefix_pico_short),
DefaultUnit(MyUnitIDS.prefix_femto, BigDecimal.valueOf(1E-15), UnitGroup.PREFIX, R.string.prefix_femto, R.string.prefix_femto_short),
DefaultUnit(MyUnitIDS.prefix_atto, BigDecimal.valueOf(1E-18), UnitGroup.PREFIX, R.string.prefix_atto, R.string.prefix_atto_short),
DefaultUnit(MyUnitIDS.prefix_zepto, BigDecimal.valueOf(1E-21), UnitGroup.PREFIX, R.string.prefix_zepto, R.string.prefix_zepto_short),
DefaultUnit(MyUnitIDS.prefix_yocto, BigDecimal.valueOf(1E-24), UnitGroup.PREFIX, R.string.prefix_yocto, R.string.prefix_yocto_short),
DefaultUnit(MyUnitIDS.prefix_ronto, BigDecimal.valueOf(1E-27), UnitGroup.PREFIX, R.string.prefix_ronto, R.string.prefix_ronto_short),
DefaultUnit(MyUnitIDS.prefix_quecto, BigDecimal.valueOf(1E-30), UnitGroup.PREFIX, R.string.prefix_quecto, R.string.prefix_quecto_short),
NormalUnit(MyUnitIDS.prefix_quetta, BigDecimal.valueOf(1E+30), UnitGroup.PREFIX, R.string.prefix_quetta, R.string.prefix_quetta_short),
NormalUnit(MyUnitIDS.prefix_ronna, BigDecimal.valueOf(1E+27), UnitGroup.PREFIX, R.string.prefix_ronna, R.string.prefix_ronna_short),
NormalUnit(MyUnitIDS.prefix_yotta, BigDecimal.valueOf(1E+24), UnitGroup.PREFIX, R.string.prefix_yotta, R.string.prefix_yotta_short),
NormalUnit(MyUnitIDS.prefix_zetta, BigDecimal.valueOf(1E+21), UnitGroup.PREFIX, R.string.prefix_zetta, R.string.prefix_zetta_short),
NormalUnit(MyUnitIDS.prefix_exa, BigDecimal.valueOf(1E+18), UnitGroup.PREFIX, R.string.prefix_exa, R.string.prefix_exa_short),
NormalUnit(MyUnitIDS.prefix_peta, BigDecimal.valueOf(1E+15), UnitGroup.PREFIX, R.string.prefix_peta, R.string.prefix_peta_short),
NormalUnit(MyUnitIDS.prefix_tera, BigDecimal.valueOf(1E+12), UnitGroup.PREFIX, R.string.prefix_tera, R.string.prefix_tera_short),
NormalUnit(MyUnitIDS.prefix_giga, BigDecimal.valueOf(1E+9), UnitGroup.PREFIX, R.string.prefix_giga, R.string.prefix_giga_short),
NormalUnit(MyUnitIDS.prefix_mega, BigDecimal.valueOf(1E+6), UnitGroup.PREFIX, R.string.prefix_mega, R.string.prefix_mega_short),
NormalUnit(MyUnitIDS.prefix_kilo, BigDecimal.valueOf(1E+3), UnitGroup.PREFIX, R.string.prefix_kilo, R.string.prefix_kilo_short),
NormalUnit(MyUnitIDS.prefix_hecto, BigDecimal.valueOf(1E+2), UnitGroup.PREFIX, R.string.prefix_hecto, R.string.prefix_hecto_short),
NormalUnit(MyUnitIDS.prefix_deca, BigDecimal.valueOf(1E+1), UnitGroup.PREFIX, R.string.prefix_deca, R.string.prefix_deca_short),
NormalUnit(MyUnitIDS.prefix_base, BigDecimal.valueOf(1E+0), UnitGroup.PREFIX, R.string.prefix_base, R.string.prefix_base_short),
NormalUnit(MyUnitIDS.prefix_deci, BigDecimal.valueOf(1E-1), UnitGroup.PREFIX, R.string.prefix_deci, R.string.prefix_deci_short),
NormalUnit(MyUnitIDS.prefix_centi, BigDecimal.valueOf(1E-2), UnitGroup.PREFIX, R.string.prefix_centi, R.string.prefix_centi_short),
NormalUnit(MyUnitIDS.prefix_milli, BigDecimal.valueOf(1E-3), UnitGroup.PREFIX, R.string.prefix_milli, R.string.prefix_milli_short),
NormalUnit(MyUnitIDS.prefix_micro, BigDecimal.valueOf(1E-6), UnitGroup.PREFIX, R.string.prefix_micro, R.string.prefix_micro_short),
NormalUnit(MyUnitIDS.prefix_nano, BigDecimal.valueOf(1E-9), UnitGroup.PREFIX, R.string.prefix_nano, R.string.prefix_nano_short),
NormalUnit(MyUnitIDS.prefix_pico, BigDecimal.valueOf(1E-12), UnitGroup.PREFIX, R.string.prefix_pico, R.string.prefix_pico_short),
NormalUnit(MyUnitIDS.prefix_femto, BigDecimal.valueOf(1E-15), UnitGroup.PREFIX, R.string.prefix_femto, R.string.prefix_femto_short),
NormalUnit(MyUnitIDS.prefix_atto, BigDecimal.valueOf(1E-18), UnitGroup.PREFIX, R.string.prefix_atto, R.string.prefix_atto_short),
NormalUnit(MyUnitIDS.prefix_zepto, BigDecimal.valueOf(1E-21), UnitGroup.PREFIX, R.string.prefix_zepto, R.string.prefix_zepto_short),
NormalUnit(MyUnitIDS.prefix_yocto, BigDecimal.valueOf(1E-24), UnitGroup.PREFIX, R.string.prefix_yocto, R.string.prefix_yocto_short),
NormalUnit(MyUnitIDS.prefix_ronto, BigDecimal.valueOf(1E-27), UnitGroup.PREFIX, R.string.prefix_ronto, R.string.prefix_ronto_short),
NormalUnit(MyUnitIDS.prefix_quecto, BigDecimal.valueOf(1E-30), UnitGroup.PREFIX, R.string.prefix_quecto, R.string.prefix_quecto_short),
)
}

View File

@ -19,38 +19,38 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val pressureCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.attopascal, BigDecimal.valueOf(1), UnitGroup.PRESSURE, R.string.attopascal, R.string.attopascal_short),
DefaultUnit(MyUnitIDS.femtopascal, BigDecimal.valueOf(1E+3), UnitGroup.PRESSURE, R.string.femtopascal, R.string.femtopascal_short),
DefaultUnit(MyUnitIDS.picopascal, BigDecimal.valueOf(1E+6), UnitGroup.PRESSURE, R.string.picopascal, R.string.picopascal_short),
DefaultUnit(MyUnitIDS.nanopascal, BigDecimal.valueOf(1E+9), UnitGroup.PRESSURE, R.string.nanopascal, R.string.nanopascal_short),
DefaultUnit(MyUnitIDS.micropascal, BigDecimal.valueOf(1E+12), UnitGroup.PRESSURE, R.string.micropascal, R.string.micropascal_short),
DefaultUnit(MyUnitIDS.millipascal, BigDecimal.valueOf(1E+15), UnitGroup.PRESSURE, R.string.millipascal, R.string.millipascal_short),
DefaultUnit(MyUnitIDS.centipascal, BigDecimal.valueOf(1E+16), UnitGroup.PRESSURE, R.string.centipascal, R.string.centipascal_short),
DefaultUnit(MyUnitIDS.decipascal, BigDecimal.valueOf(1E+17), UnitGroup.PRESSURE, R.string.decipascal, R.string.decipascal_short),
DefaultUnit(MyUnitIDS.pascal, BigDecimal.valueOf(1E+18), UnitGroup.PRESSURE, R.string.pascal, R.string.pascal_short),
DefaultUnit(MyUnitIDS.dekapascal, BigDecimal.valueOf(1E+19), UnitGroup.PRESSURE, R.string.dekapascal, R.string.dekapascal_short),
DefaultUnit(MyUnitIDS.hectopascal, BigDecimal.valueOf(1E+20), UnitGroup.PRESSURE, R.string.hectopascal, R.string.hectopascal_short),
DefaultUnit(MyUnitIDS.millibar, BigDecimal.valueOf(1E+20), UnitGroup.PRESSURE, R.string.millibar, R.string.millibar_short),
DefaultUnit(MyUnitIDS.bar, BigDecimal.valueOf(1E+23), UnitGroup.PRESSURE, R.string.bar, R.string.bar_short),
DefaultUnit(MyUnitIDS.kilopascal, BigDecimal.valueOf(1E+21), UnitGroup.PRESSURE, R.string.kilopascal, R.string.kilopascal_short),
DefaultUnit(MyUnitIDS.megapascal, BigDecimal.valueOf(1E+24), UnitGroup.PRESSURE, R.string.megapascal, R.string.megapascal_short),
DefaultUnit(MyUnitIDS.gigapascal, BigDecimal.valueOf(1E+27), UnitGroup.PRESSURE, R.string.gigapascal, R.string.gigapascal_short),
DefaultUnit(MyUnitIDS.terapascal, BigDecimal.valueOf(1E+30), UnitGroup.PRESSURE, R.string.terapascal, R.string.terapascal_short),
DefaultUnit(MyUnitIDS.petapascal, BigDecimal.valueOf(1E+33), UnitGroup.PRESSURE, R.string.petapascal, R.string.petapascal_short),
DefaultUnit(MyUnitIDS.exapascal, BigDecimal.valueOf(1E+36), UnitGroup.PRESSURE, R.string.exapascal, R.string.exapascal_short),
DefaultUnit(MyUnitIDS.psi, BigDecimal.valueOf(6.8947572931783E+21), UnitGroup.PRESSURE, R.string.psi, R.string.psi_short),
DefaultUnit(MyUnitIDS.ksi, BigDecimal.valueOf(6.8947572931783E+24), UnitGroup.PRESSURE, R.string.ksi, R.string.ksi_short),
DefaultUnit(MyUnitIDS.standard_atmosphere, BigDecimal.valueOf(101.325E+21), UnitGroup.PRESSURE, R.string.standard_atmosphere, R.string.standard_atmosphere_short),
DefaultUnit(MyUnitIDS.torr, BigDecimal.valueOf(1.3332236842108281E+20), UnitGroup.PRESSURE, R.string.torr, R.string.torr_short),
DefaultUnit(MyUnitIDS.micron_of_mercury, BigDecimal.valueOf(1.3332236842108281E+17), UnitGroup.PRESSURE, R.string.micron_of_mercury, R.string.micron_of_mercury_short),
DefaultUnit(MyUnitIDS.millimeter_of_mercury, BigDecimal.valueOf(1.3332236842108281E+20), UnitGroup.PRESSURE, R.string.millimeter_of_mercury, R.string.millimeter_of_mercury_short),
NormalUnit(MyUnitIDS.attopascal, BigDecimal.valueOf(1), UnitGroup.PRESSURE, R.string.attopascal, R.string.attopascal_short),
NormalUnit(MyUnitIDS.femtopascal, BigDecimal.valueOf(1E+3), UnitGroup.PRESSURE, R.string.femtopascal, R.string.femtopascal_short),
NormalUnit(MyUnitIDS.picopascal, BigDecimal.valueOf(1E+6), UnitGroup.PRESSURE, R.string.picopascal, R.string.picopascal_short),
NormalUnit(MyUnitIDS.nanopascal, BigDecimal.valueOf(1E+9), UnitGroup.PRESSURE, R.string.nanopascal, R.string.nanopascal_short),
NormalUnit(MyUnitIDS.micropascal, BigDecimal.valueOf(1E+12), UnitGroup.PRESSURE, R.string.micropascal, R.string.micropascal_short),
NormalUnit(MyUnitIDS.millipascal, BigDecimal.valueOf(1E+15), UnitGroup.PRESSURE, R.string.millipascal, R.string.millipascal_short),
NormalUnit(MyUnitIDS.centipascal, BigDecimal.valueOf(1E+16), UnitGroup.PRESSURE, R.string.centipascal, R.string.centipascal_short),
NormalUnit(MyUnitIDS.decipascal, BigDecimal.valueOf(1E+17), UnitGroup.PRESSURE, R.string.decipascal, R.string.decipascal_short),
NormalUnit(MyUnitIDS.pascal, BigDecimal.valueOf(1E+18), UnitGroup.PRESSURE, R.string.pascal, R.string.pascal_short),
NormalUnit(MyUnitIDS.dekapascal, BigDecimal.valueOf(1E+19), UnitGroup.PRESSURE, R.string.dekapascal, R.string.dekapascal_short),
NormalUnit(MyUnitIDS.hectopascal, BigDecimal.valueOf(1E+20), UnitGroup.PRESSURE, R.string.hectopascal, R.string.hectopascal_short),
NormalUnit(MyUnitIDS.millibar, BigDecimal.valueOf(1E+20), UnitGroup.PRESSURE, R.string.millibar, R.string.millibar_short),
NormalUnit(MyUnitIDS.bar, BigDecimal.valueOf(1E+23), UnitGroup.PRESSURE, R.string.bar, R.string.bar_short),
NormalUnit(MyUnitIDS.kilopascal, BigDecimal.valueOf(1E+21), UnitGroup.PRESSURE, R.string.kilopascal, R.string.kilopascal_short),
NormalUnit(MyUnitIDS.megapascal, BigDecimal.valueOf(1E+24), UnitGroup.PRESSURE, R.string.megapascal, R.string.megapascal_short),
NormalUnit(MyUnitIDS.gigapascal, BigDecimal.valueOf(1E+27), UnitGroup.PRESSURE, R.string.gigapascal, R.string.gigapascal_short),
NormalUnit(MyUnitIDS.terapascal, BigDecimal.valueOf(1E+30), UnitGroup.PRESSURE, R.string.terapascal, R.string.terapascal_short),
NormalUnit(MyUnitIDS.petapascal, BigDecimal.valueOf(1E+33), UnitGroup.PRESSURE, R.string.petapascal, R.string.petapascal_short),
NormalUnit(MyUnitIDS.exapascal, BigDecimal.valueOf(1E+36), UnitGroup.PRESSURE, R.string.exapascal, R.string.exapascal_short),
NormalUnit(MyUnitIDS.psi, BigDecimal.valueOf(6.8947572931783E+21), UnitGroup.PRESSURE, R.string.psi, R.string.psi_short),
NormalUnit(MyUnitIDS.ksi, BigDecimal.valueOf(6.8947572931783E+24), UnitGroup.PRESSURE, R.string.ksi, R.string.ksi_short),
NormalUnit(MyUnitIDS.standard_atmosphere, BigDecimal.valueOf(101.325E+21), UnitGroup.PRESSURE, R.string.standard_atmosphere, R.string.standard_atmosphere_short),
NormalUnit(MyUnitIDS.torr, BigDecimal.valueOf(1.3332236842108281E+20), UnitGroup.PRESSURE, R.string.torr, R.string.torr_short),
NormalUnit(MyUnitIDS.micron_of_mercury, BigDecimal.valueOf(1.3332236842108281E+17), UnitGroup.PRESSURE, R.string.micron_of_mercury, R.string.micron_of_mercury_short),
NormalUnit(MyUnitIDS.millimeter_of_mercury, BigDecimal.valueOf(1.3332236842108281E+20), UnitGroup.PRESSURE, R.string.millimeter_of_mercury, R.string.millimeter_of_mercury_short),
)
}
}

View File

@ -19,42 +19,42 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val speedCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.millimeter_per_hour, BigDecimal.valueOf(1), UnitGroup.SPEED, R.string.millimeter_per_hour, R.string.millimeter_per_hour_short),
DefaultUnit(MyUnitIDS.millimeter_per_minute, BigDecimal.valueOf(60), UnitGroup.SPEED, R.string.millimeter_per_minute, R.string.millimeter_per_minute_short),
DefaultUnit(MyUnitIDS.millimeter_per_second, BigDecimal.valueOf(3_600), UnitGroup.SPEED, R.string.millimeter_per_second, R.string.millimeter_per_second_short),
DefaultUnit(MyUnitIDS.centimeter_per_hour, BigDecimal.valueOf(10), UnitGroup.SPEED, R.string.centimeter_per_hour, R.string.centimeter_per_hour_short),
DefaultUnit(MyUnitIDS.centimeter_per_minute, BigDecimal.valueOf(600), UnitGroup.SPEED, R.string.centimeter_per_minute, R.string.centimeter_per_minute_short),
DefaultUnit(MyUnitIDS.centimeter_per_second, BigDecimal.valueOf(36_000), UnitGroup.SPEED, R.string.centimeter_per_second, R.string.centimeter_per_second_short),
DefaultUnit(MyUnitIDS.meter_per_hour, BigDecimal.valueOf(1_000), UnitGroup.SPEED, R.string.meter_per_hour, R.string.meter_per_hour_short),
DefaultUnit(MyUnitIDS.meter_per_minute, BigDecimal.valueOf(60_000), UnitGroup.SPEED, R.string.meter_per_minute, R.string.meter_per_minute_short),
DefaultUnit(MyUnitIDS.meter_per_second, BigDecimal.valueOf(3_600_000), UnitGroup.SPEED, R.string.meter_per_second, R.string.meter_per_second_short),
DefaultUnit(MyUnitIDS.kilometer_per_hour, BigDecimal.valueOf(1_000_000), UnitGroup.SPEED, R.string.kilometer_per_hour, R.string.kilometer_per_hour_short),
DefaultUnit(MyUnitIDS.kilometer_per_minute, BigDecimal.valueOf(60_000_000), UnitGroup.SPEED, R.string.kilometer_per_minute, R.string.kilometer_per_minute_short),
DefaultUnit(MyUnitIDS.kilometer_per_second, BigDecimal.valueOf(3_600_000_000), UnitGroup.SPEED, R.string.kilometer_per_second, R.string.kilometer_per_second_short),
DefaultUnit(MyUnitIDS.foot_per_hour, BigDecimal.valueOf(304.8), UnitGroup.SPEED, R.string.foot_per_hour, R.string.foot_per_hour_short),
DefaultUnit(MyUnitIDS.foot_per_minute, BigDecimal.valueOf(18_288), UnitGroup.SPEED, R.string.foot_per_minute, R.string.foot_per_minute_short),
DefaultUnit(MyUnitIDS.foot_per_second, BigDecimal.valueOf(1_097_280), UnitGroup.SPEED, R.string.foot_per_second, R.string.foot_per_second_short),
DefaultUnit(MyUnitIDS.yard_per_hour, BigDecimal.valueOf(914.4), UnitGroup.SPEED, R.string.yard_per_hour, R.string.yard_per_hour_short),
DefaultUnit(MyUnitIDS.yard_per_minute, BigDecimal.valueOf(54_864), UnitGroup.SPEED, R.string.yard_per_minute, R.string.yard_per_minute_short),
DefaultUnit(MyUnitIDS.yard_per_second, BigDecimal.valueOf(3_291_840), UnitGroup.SPEED, R.string.yard_per_second, R.string.yard_per_second_short),
DefaultUnit(MyUnitIDS.mile_per_hour, BigDecimal.valueOf(1_609_344), UnitGroup.SPEED, R.string.mile_per_hour, R.string.mile_per_hour_short),
DefaultUnit(MyUnitIDS.mile_per_minute, BigDecimal.valueOf(96_560_640), UnitGroup.SPEED, R.string.mile_per_minute, R.string.mile_per_minute_short),
DefaultUnit(MyUnitIDS.mile_per_second, BigDecimal.valueOf(5_793_638_400), UnitGroup.SPEED, R.string.mile_per_second, R.string.mile_per_second_short),
DefaultUnit(MyUnitIDS.knot, BigDecimal.valueOf(1_852_000), UnitGroup.SPEED, R.string.knot, R.string.knot_short),
DefaultUnit(MyUnitIDS.velocity_of_light_in_vacuum, BigDecimal.valueOf(1_079_252_848_799_998), UnitGroup.SPEED, R.string.velocity_of_light_in_vacuum, R.string.velocity_of_light_in_vacuum_short),
DefaultUnit(MyUnitIDS.cosmic_velocity_first, BigDecimal.valueOf(28_440_000_000), UnitGroup.SPEED, R.string.cosmic_velocity_first, R.string.cosmic_velocity_first_short),
DefaultUnit(MyUnitIDS.cosmic_velocity_second, BigDecimal.valueOf(40_320_000_000), UnitGroup.SPEED, R.string.cosmic_velocity_second, R.string.cosmic_velocity_second_short),
DefaultUnit(MyUnitIDS.cosmic_velocity_third, BigDecimal.valueOf(60_012_000_000), UnitGroup.SPEED, R.string.cosmic_velocity_third, R.string.cosmic_velocity_third_short),
DefaultUnit(MyUnitIDS.earths_orbital_speed, BigDecimal.valueOf(107_154_000_000), UnitGroup.SPEED, R.string.earths_orbital_speed, R.string.earths_orbital_speed_short),
DefaultUnit(MyUnitIDS.mach, BigDecimal.valueOf(1_236_960_000), UnitGroup.SPEED, R.string.mach, R.string.mach_short),
DefaultUnit(MyUnitIDS.mach_si_standard, BigDecimal.valueOf(1_062_167_040), UnitGroup.SPEED, R.string.mach_si_standard, R.string.mach_si_standard_short),
NormalUnit(MyUnitIDS.millimeter_per_hour, BigDecimal.valueOf(1), UnitGroup.SPEED, R.string.millimeter_per_hour, R.string.millimeter_per_hour_short),
NormalUnit(MyUnitIDS.millimeter_per_minute, BigDecimal.valueOf(60), UnitGroup.SPEED, R.string.millimeter_per_minute, R.string.millimeter_per_minute_short),
NormalUnit(MyUnitIDS.millimeter_per_second, BigDecimal.valueOf(3_600), UnitGroup.SPEED, R.string.millimeter_per_second, R.string.millimeter_per_second_short),
NormalUnit(MyUnitIDS.centimeter_per_hour, BigDecimal.valueOf(10), UnitGroup.SPEED, R.string.centimeter_per_hour, R.string.centimeter_per_hour_short),
NormalUnit(MyUnitIDS.centimeter_per_minute, BigDecimal.valueOf(600), UnitGroup.SPEED, R.string.centimeter_per_minute, R.string.centimeter_per_minute_short),
NormalUnit(MyUnitIDS.centimeter_per_second, BigDecimal.valueOf(36_000), UnitGroup.SPEED, R.string.centimeter_per_second, R.string.centimeter_per_second_short),
NormalUnit(MyUnitIDS.meter_per_hour, BigDecimal.valueOf(1_000), UnitGroup.SPEED, R.string.meter_per_hour, R.string.meter_per_hour_short),
NormalUnit(MyUnitIDS.meter_per_minute, BigDecimal.valueOf(60_000), UnitGroup.SPEED, R.string.meter_per_minute, R.string.meter_per_minute_short),
NormalUnit(MyUnitIDS.meter_per_second, BigDecimal.valueOf(3_600_000), UnitGroup.SPEED, R.string.meter_per_second, R.string.meter_per_second_short),
NormalUnit(MyUnitIDS.kilometer_per_hour, BigDecimal.valueOf(1_000_000), UnitGroup.SPEED, R.string.kilometer_per_hour, R.string.kilometer_per_hour_short),
NormalUnit(MyUnitIDS.kilometer_per_minute, BigDecimal.valueOf(60_000_000), UnitGroup.SPEED, R.string.kilometer_per_minute, R.string.kilometer_per_minute_short),
NormalUnit(MyUnitIDS.kilometer_per_second, BigDecimal.valueOf(3_600_000_000), UnitGroup.SPEED, R.string.kilometer_per_second, R.string.kilometer_per_second_short),
NormalUnit(MyUnitIDS.foot_per_hour, BigDecimal.valueOf(304.8), UnitGroup.SPEED, R.string.foot_per_hour, R.string.foot_per_hour_short),
NormalUnit(MyUnitIDS.foot_per_minute, BigDecimal.valueOf(18_288), UnitGroup.SPEED, R.string.foot_per_minute, R.string.foot_per_minute_short),
NormalUnit(MyUnitIDS.foot_per_second, BigDecimal.valueOf(1_097_280), UnitGroup.SPEED, R.string.foot_per_second, R.string.foot_per_second_short),
NormalUnit(MyUnitIDS.yard_per_hour, BigDecimal.valueOf(914.4), UnitGroup.SPEED, R.string.yard_per_hour, R.string.yard_per_hour_short),
NormalUnit(MyUnitIDS.yard_per_minute, BigDecimal.valueOf(54_864), UnitGroup.SPEED, R.string.yard_per_minute, R.string.yard_per_minute_short),
NormalUnit(MyUnitIDS.yard_per_second, BigDecimal.valueOf(3_291_840), UnitGroup.SPEED, R.string.yard_per_second, R.string.yard_per_second_short),
NormalUnit(MyUnitIDS.mile_per_hour, BigDecimal.valueOf(1_609_344), UnitGroup.SPEED, R.string.mile_per_hour, R.string.mile_per_hour_short),
NormalUnit(MyUnitIDS.mile_per_minute, BigDecimal.valueOf(96_560_640), UnitGroup.SPEED, R.string.mile_per_minute, R.string.mile_per_minute_short),
NormalUnit(MyUnitIDS.mile_per_second, BigDecimal.valueOf(5_793_638_400), UnitGroup.SPEED, R.string.mile_per_second, R.string.mile_per_second_short),
NormalUnit(MyUnitIDS.knot, BigDecimal.valueOf(1_852_000), UnitGroup.SPEED, R.string.knot, R.string.knot_short),
NormalUnit(MyUnitIDS.velocity_of_light_in_vacuum, BigDecimal.valueOf(1_079_252_848_799_998), UnitGroup.SPEED, R.string.velocity_of_light_in_vacuum, R.string.velocity_of_light_in_vacuum_short),
NormalUnit(MyUnitIDS.cosmic_velocity_first, BigDecimal.valueOf(28_440_000_000), UnitGroup.SPEED, R.string.cosmic_velocity_first, R.string.cosmic_velocity_first_short),
NormalUnit(MyUnitIDS.cosmic_velocity_second, BigDecimal.valueOf(40_320_000_000), UnitGroup.SPEED, R.string.cosmic_velocity_second, R.string.cosmic_velocity_second_short),
NormalUnit(MyUnitIDS.cosmic_velocity_third, BigDecimal.valueOf(60_012_000_000), UnitGroup.SPEED, R.string.cosmic_velocity_third, R.string.cosmic_velocity_third_short),
NormalUnit(MyUnitIDS.earths_orbital_speed, BigDecimal.valueOf(107_154_000_000), UnitGroup.SPEED, R.string.earths_orbital_speed, R.string.earths_orbital_speed_short),
NormalUnit(MyUnitIDS.mach, BigDecimal.valueOf(1_236_960_000), UnitGroup.SPEED, R.string.mach, R.string.mach_short),
NormalUnit(MyUnitIDS.mach_si_standard, BigDecimal.valueOf(1_062_167_040), UnitGroup.SPEED, R.string.mach_si_standard, R.string.mach_si_standard_short),
)
}
}

View File

@ -20,98 +20,104 @@ package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.MAX_PRECISION
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.common.setMinimumRequiredScale
import com.sadellie.unitto.data.common.trimZeros
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.DefaultUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
import java.math.RoundingMode
internal val temperatureCollection: List<AbstractUnit> by lazy {
listOf(
object : AbstractUnit(
unitId = MyUnitIDS.celsius,
basicUnit = BigDecimal.ONE,
group = UnitGroup.TEMPERATURE,
displayName = R.string.celsius,
shortName = R.string.celsius_short,
) {
override fun convert(unitTo: AbstractUnit, value: BigDecimal, scale: Int): BigDecimal {
return when (unitTo.unitId) {
MyUnitIDS.fahrenheit -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.times(BigDecimal.valueOf(1.8))
.plus(BigDecimal(32))
}
MyUnitIDS.kelvin -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.plus(BigDecimal.valueOf(273.15))
}
else -> value
}
.setMinimumRequiredScale(scale)
.trimZeros()
listOf(celsius, fahrenheit, kelvin)
}
private val celsius = object : DefaultUnit {
override val id: String = MyUnitIDS.celsius
override val basicUnit: BigDecimal = BigDecimal.ONE
override val group: UnitGroup = UnitGroup.TEMPERATURE
override val displayName: Int = R.string.celsius
override val shortName: Int = R.string.celsius_short
override val isFavorite: Boolean = false
override val pairId: String? = null
override val counter: Int = 0
override fun convert(unitTo: DefaultUnit, value: BigDecimal): BigDecimal {
return when (unitTo.id) {
MyUnitIDS.fahrenheit -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.times(BigDecimal.valueOf(1.8))
.plus(BigDecimal(32))
}
},
object : AbstractUnit(
unitId = MyUnitIDS.fahrenheit,
basicUnit = BigDecimal.ONE,
group = UnitGroup.TEMPERATURE,
displayName = R.string.fahrenheit,
shortName = R.string.fahrenheit_short,
) {
override fun convert(unitTo: AbstractUnit, value: BigDecimal, scale: Int): BigDecimal {
return when (unitTo.unitId) {
MyUnitIDS.celsius -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal(32))
.times(BigDecimal(5))
.div(BigDecimal(9))
}
MyUnitIDS.kelvin -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal(32))
.times(BigDecimal(5))
.div(BigDecimal(9))
.add(BigDecimal.valueOf(273.15))
}
else -> value
}
.setMinimumRequiredScale(scale)
.trimZeros()
MyUnitIDS.kelvin -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.plus(BigDecimal.valueOf(273.15))
}
},
object : AbstractUnit(
unitId = MyUnitIDS.kelvin,
basicUnit = BigDecimal.ONE,
group = UnitGroup.TEMPERATURE,
displayName = R.string.kelvin,
shortName = R.string.kelvin_short,
) {
override fun convert(unitTo: AbstractUnit, value: BigDecimal, scale: Int): BigDecimal {
return when (unitTo.unitId) {
MyUnitIDS.celsius -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal(273.15))
}
MyUnitIDS.fahrenheit -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal.valueOf(273.15))
.times(BigDecimal.valueOf(1.8))
.plus(BigDecimal(32))
}
else -> value
}
.setMinimumRequiredScale(scale)
.trimZeros()
else -> value
}
}
}
private val fahrenheit = object : DefaultUnit {
override val id: String = MyUnitIDS.fahrenheit
override val basicUnit: BigDecimal = BigDecimal.ONE
override val group: UnitGroup = UnitGroup.TEMPERATURE
override val displayName: Int = R.string.fahrenheit
override val shortName: Int = R.string.fahrenheit_short
override val isFavorite: Boolean = false
override val pairId: String? = null
override val counter: Int = 0
override fun convert(unitTo: DefaultUnit, value: BigDecimal): BigDecimal {
return when (unitTo.id) {
MyUnitIDS.celsius -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal(32))
.times(BigDecimal(5))
.div(BigDecimal(9))
}
},
)
}
MyUnitIDS.kelvin -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal(32))
.times(BigDecimal(5))
.div(BigDecimal(9))
.add(BigDecimal.valueOf(273.15))
}
else -> value
}
}
}
private val kelvin = object : DefaultUnit {
override val id: String = MyUnitIDS.kelvin
override val basicUnit: BigDecimal = BigDecimal.ONE
override val group: UnitGroup = UnitGroup.TEMPERATURE
override val displayName: Int = R.string.kelvin
override val shortName: Int = R.string.kelvin_short
override val isFavorite: Boolean = false
override val pairId: String? = null
override val counter: Int = 0
override fun convert(unitTo: DefaultUnit, value: BigDecimal): BigDecimal {
return when (unitTo.id) {
MyUnitIDS.celsius -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal(273.15))
}
MyUnitIDS.fahrenheit -> {
value
.setScale(MAX_PRECISION, RoundingMode.HALF_EVEN)
.minus(BigDecimal.valueOf(273.15))
.times(BigDecimal.valueOf(1.8))
.plus(BigDecimal(32))
}
else -> value
}
}
}

View File

@ -19,23 +19,23 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val timeCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.attosecond, BigDecimal.valueOf(1), UnitGroup.TIME, R.string.attosecond, R.string.attosecond_short),
DefaultUnit(MyUnitIDS.nanosecond, BigDecimal.valueOf(1_000_000_000), UnitGroup.TIME, R.string.nanosecond, R.string.nanosecond_short),
DefaultUnit(MyUnitIDS.microsecond, BigDecimal.valueOf(1_000_000_000_000), UnitGroup.TIME, R.string.microsecond, R.string.microsecond_short),
DefaultUnit(MyUnitIDS.millisecond, BigDecimal.valueOf(1_000_000_000_000_000), UnitGroup.TIME, R.string.millisecond, R.string.millisecond_short),
DefaultUnit(MyUnitIDS.jiffy, BigDecimal.valueOf(10_000_000_000_000_000), UnitGroup.TIME, R.string.jiffy, R.string.jiffy_short),
DefaultUnit(MyUnitIDS.second, BigDecimal.valueOf(1_000_000_000_000_000_000), UnitGroup.TIME, R.string.second, R.string.second_short),
DefaultUnit(MyUnitIDS.minute, BigDecimal.valueOf(60_000_000_000_000_000_000.0), UnitGroup.TIME, R.string.minute, R.string.minute_short),
DefaultUnit(MyUnitIDS.hour, BigDecimal.valueOf(3_600_000_000_000_000_000_000.0), UnitGroup.TIME, R.string.hour, R.string.hour_short),
DefaultUnit(MyUnitIDS.day, BigDecimal.valueOf(86_400_000_000_000_000_000_000.0), UnitGroup.TIME, R.string.day, R.string.day_short),
DefaultUnit(MyUnitIDS.week, BigDecimal.valueOf(604_800_000_000_000_000_000_000.0), UnitGroup.TIME, R.string.week, R.string.week_short),
NormalUnit(MyUnitIDS.attosecond, BigDecimal.valueOf(1), UnitGroup.TIME, R.string.attosecond, R.string.attosecond_short),
NormalUnit(MyUnitIDS.nanosecond, BigDecimal.valueOf(1_000_000_000), UnitGroup.TIME, R.string.nanosecond, R.string.nanosecond_short),
NormalUnit(MyUnitIDS.microsecond, BigDecimal.valueOf(1_000_000_000_000), UnitGroup.TIME, R.string.microsecond, R.string.microsecond_short),
NormalUnit(MyUnitIDS.millisecond, BigDecimal.valueOf(1_000_000_000_000_000), UnitGroup.TIME, R.string.millisecond, R.string.millisecond_short),
NormalUnit(MyUnitIDS.jiffy, BigDecimal.valueOf(10_000_000_000_000_000), UnitGroup.TIME, R.string.jiffy, R.string.jiffy_short),
NormalUnit(MyUnitIDS.second, BigDecimal.valueOf(1_000_000_000_000_000_000), UnitGroup.TIME, R.string.second, R.string.second_short),
NormalUnit(MyUnitIDS.minute, BigDecimal.valueOf(60_000_000_000_000_000_000.0), UnitGroup.TIME, R.string.minute, R.string.minute_short),
NormalUnit(MyUnitIDS.hour, BigDecimal.valueOf(3_600_000_000_000_000_000_000.0), UnitGroup.TIME, R.string.hour, R.string.hour_short),
NormalUnit(MyUnitIDS.day, BigDecimal.valueOf(86_400_000_000_000_000_000_000.0), UnitGroup.TIME, R.string.day, R.string.day_short),
NormalUnit(MyUnitIDS.week, BigDecimal.valueOf(604_800_000_000_000_000_000_000.0), UnitGroup.TIME, R.string.week, R.string.week_short),
)
}
}

View File

@ -19,30 +19,30 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
val torqueCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.dyne_millimeter, BigDecimal.valueOf(1), UnitGroup.TORQUE, R.string.dyne_millimeter, R.string.dyne_millimeter_short),
DefaultUnit(MyUnitIDS.dyne_centimeter, BigDecimal.valueOf(10), UnitGroup.TORQUE, R.string.dyne_centimeter, R.string.dyne_centimeter_short),
DefaultUnit(MyUnitIDS.dyne_meter, BigDecimal.valueOf(1000), UnitGroup.TORQUE, R.string.dyne_meter, R.string.dyne_meter_short),
DefaultUnit(MyUnitIDS.newton_millimeter, BigDecimal.valueOf(100000), UnitGroup.TORQUE, R.string.newton_millimeter, R.string.newton_millimeter_short),
DefaultUnit(MyUnitIDS.newton_centimeter, BigDecimal.valueOf(1000000), UnitGroup.TORQUE, R.string.newton_centimeter, R.string.newton_centimeter_short),
DefaultUnit(MyUnitIDS.newton_meter, BigDecimal.valueOf(100000000), UnitGroup.TORQUE, R.string.newton_meter, R.string.newton_meter_short),
DefaultUnit(MyUnitIDS.kilonewton_meter, BigDecimal.valueOf(100000000000), UnitGroup.TORQUE, R.string.kilonewton_meter, R.string.kilonewton_meter_short),
DefaultUnit(MyUnitIDS.gram_force_millimeter, BigDecimal.valueOf(980.665), UnitGroup.TORQUE, R.string.gram_force_millimeter, R.string.gram_force_millimeter_short),
DefaultUnit(MyUnitIDS.gram_force_centimeter, BigDecimal.valueOf(9806.65), UnitGroup.TORQUE, R.string.gram_force_centimeter, R.string.gram_force_centimeter_short),
DefaultUnit(MyUnitIDS.kilogram_force_millimeter, BigDecimal.valueOf(980665), UnitGroup.TORQUE, R.string.kilogram_force_millimeter, R.string.kilogram_force_millimeter_short),
DefaultUnit(MyUnitIDS.gram_force_meter, BigDecimal.valueOf(980665), UnitGroup.TORQUE, R.string.gram_force_meter, R.string.gram_force_meter_short),
DefaultUnit(MyUnitIDS.kilogram_force_centimeter, BigDecimal.valueOf(9806650), UnitGroup.TORQUE, R.string.kilogram_force_centimeter, R.string.kilogram_force_centimeter_short),
DefaultUnit(MyUnitIDS.kilogram_force_meter, BigDecimal.valueOf(980665000), UnitGroup.TORQUE, R.string.kilogram_force_meter, R.string.kilogram_force_meter_short),
DefaultUnit(MyUnitIDS.ounce_force_foot, BigDecimal.valueOf(8473862.4), UnitGroup.TORQUE, R.string.ounce_force_foot, R.string.ounce_force_foot_short),
DefaultUnit(MyUnitIDS.ounce_force_inch, BigDecimal.valueOf(706155.2), UnitGroup.TORQUE, R.string.ounce_force_inch, R.string.ounce_force_inch_short),
DefaultUnit(MyUnitIDS.pound_force_foot, BigDecimal.valueOf(135581800), UnitGroup.TORQUE, R.string.pound_force_foot, R.string.pound_force_foot_short),
DefaultUnit(MyUnitIDS.pound_force_inch, BigDecimal.valueOf(1.1298483333333334E7), UnitGroup.TORQUE, R.string.pound_force_inch, R.string.pound_force_inch_short),
NormalUnit(MyUnitIDS.dyne_millimeter, BigDecimal.valueOf(1), UnitGroup.TORQUE, R.string.dyne_millimeter, R.string.dyne_millimeter_short),
NormalUnit(MyUnitIDS.dyne_centimeter, BigDecimal.valueOf(10), UnitGroup.TORQUE, R.string.dyne_centimeter, R.string.dyne_centimeter_short),
NormalUnit(MyUnitIDS.dyne_meter, BigDecimal.valueOf(1000), UnitGroup.TORQUE, R.string.dyne_meter, R.string.dyne_meter_short),
NormalUnit(MyUnitIDS.newton_millimeter, BigDecimal.valueOf(100000), UnitGroup.TORQUE, R.string.newton_millimeter, R.string.newton_millimeter_short),
NormalUnit(MyUnitIDS.newton_centimeter, BigDecimal.valueOf(1000000), UnitGroup.TORQUE, R.string.newton_centimeter, R.string.newton_centimeter_short),
NormalUnit(MyUnitIDS.newton_meter, BigDecimal.valueOf(100000000), UnitGroup.TORQUE, R.string.newton_meter, R.string.newton_meter_short),
NormalUnit(MyUnitIDS.kilonewton_meter, BigDecimal.valueOf(100000000000), UnitGroup.TORQUE, R.string.kilonewton_meter, R.string.kilonewton_meter_short),
NormalUnit(MyUnitIDS.gram_force_millimeter, BigDecimal.valueOf(980.665), UnitGroup.TORQUE, R.string.gram_force_millimeter, R.string.gram_force_millimeter_short),
NormalUnit(MyUnitIDS.gram_force_centimeter, BigDecimal.valueOf(9806.65), UnitGroup.TORQUE, R.string.gram_force_centimeter, R.string.gram_force_centimeter_short),
NormalUnit(MyUnitIDS.kilogram_force_millimeter, BigDecimal.valueOf(980665), UnitGroup.TORQUE, R.string.kilogram_force_millimeter, R.string.kilogram_force_millimeter_short),
NormalUnit(MyUnitIDS.gram_force_meter, BigDecimal.valueOf(980665), UnitGroup.TORQUE, R.string.gram_force_meter, R.string.gram_force_meter_short),
NormalUnit(MyUnitIDS.kilogram_force_centimeter, BigDecimal.valueOf(9806650), UnitGroup.TORQUE, R.string.kilogram_force_centimeter, R.string.kilogram_force_centimeter_short),
NormalUnit(MyUnitIDS.kilogram_force_meter, BigDecimal.valueOf(980665000), UnitGroup.TORQUE, R.string.kilogram_force_meter, R.string.kilogram_force_meter_short),
NormalUnit(MyUnitIDS.ounce_force_foot, BigDecimal.valueOf(8473862.4), UnitGroup.TORQUE, R.string.ounce_force_foot, R.string.ounce_force_foot_short),
NormalUnit(MyUnitIDS.ounce_force_inch, BigDecimal.valueOf(706155.2), UnitGroup.TORQUE, R.string.ounce_force_inch, R.string.ounce_force_inch_short),
NormalUnit(MyUnitIDS.pound_force_foot, BigDecimal.valueOf(135581800), UnitGroup.TORQUE, R.string.pound_force_foot, R.string.pound_force_foot_short),
NormalUnit(MyUnitIDS.pound_force_inch, BigDecimal.valueOf(1.1298483333333334E7), UnitGroup.TORQUE, R.string.pound_force_inch, R.string.pound_force_inch_short),
)
}

View File

@ -19,34 +19,34 @@
package com.sadellie.unitto.data.units.collections
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.units.MyUnitIDS
import java.math.BigDecimal
internal val volumeCollection: List<AbstractUnit> by lazy {
listOf(
DefaultUnit(MyUnitIDS.attoliter, BigDecimal.valueOf(1), UnitGroup.VOLUME, R.string.attoliter, R.string.attoliter_short),
DefaultUnit(MyUnitIDS.milliliter, BigDecimal.valueOf(1_000_000_000_000_000), UnitGroup.VOLUME, R.string.milliliter, R.string.milliliter_short),
DefaultUnit(MyUnitIDS.liter, BigDecimal.valueOf(1_000_000_000_000_000_000), UnitGroup.VOLUME, R.string.liter, R.string.liter_short),
DefaultUnit(MyUnitIDS.us_liquid_gallon, BigDecimal.valueOf(3_785_411_783_999_977_000), UnitGroup.VOLUME, R.string.us_liquid_gallon, R.string.us_liquid_gallon_short),
DefaultUnit(MyUnitIDS.us_liquid_quart, BigDecimal.valueOf(946_352_945_999_994_200), UnitGroup.VOLUME, R.string.us_liquid_quart, R.string.us_liquid_quart_short),
DefaultUnit(MyUnitIDS.us_liquid_pint, BigDecimal.valueOf(473_176_472_999_997_100), UnitGroup.VOLUME, R.string.us_liquid_pint, R.string.us_liquid_pint_short),
DefaultUnit(MyUnitIDS.us_legal_cup, BigDecimal.valueOf(236_588_236_499_998_560), UnitGroup.VOLUME, R.string.us_legal_cup, R.string.us_legal_cup_short),
DefaultUnit(MyUnitIDS.us_fluid_ounce, BigDecimal.valueOf(29_573_529_562_499_996), UnitGroup.VOLUME, R.string.us_fluid_ounce, R.string.us_fluid_ounce_short),
DefaultUnit(MyUnitIDS.us_tablespoon, BigDecimal.valueOf(14_786_764_781_249_998), UnitGroup.VOLUME, R.string.us_tablespoon, R.string.us_tablespoon_short),
DefaultUnit(MyUnitIDS.us_teaspoon, BigDecimal.valueOf(4_928_921_593_749_952), UnitGroup.VOLUME, R.string.us_teaspoon, R.string.us_teaspoon_short),
DefaultUnit(MyUnitIDS.imperial_gallon, BigDecimal.valueOf(4_546_089_999_999_954_400), UnitGroup.VOLUME, R.string.imperial_gallon, R.string.imperial_gallon_short),
DefaultUnit(MyUnitIDS.imperial_quart, BigDecimal.valueOf(1_136_522_500_000_001_400), UnitGroup.VOLUME, R.string.imperial_quart, R.string.imperial_quart_short),
DefaultUnit(MyUnitIDS.imperial_pint, BigDecimal.valueOf(568_261_250_000_000_700), UnitGroup.VOLUME, R.string.imperial_pint, R.string.imperial_pint_short),
DefaultUnit(MyUnitIDS.imperial_cup, BigDecimal.valueOf(284_130_625_000_000_350), UnitGroup.VOLUME, R.string.imperial_cup, R.string.imperial_cup_short),
DefaultUnit(MyUnitIDS.imperial_fluid_ounce, BigDecimal.valueOf(28_413_062_500_000_036), UnitGroup.VOLUME, R.string.imperial_fluid_ounce, R.string.imperial_fluid_ounce_short),
DefaultUnit(MyUnitIDS.imperial_tablespoon, BigDecimal.valueOf(17_758_164_062_500_148), UnitGroup.VOLUME, R.string.imperial_tablespoon, R.string.imperial_tablespoon_short),
DefaultUnit(MyUnitIDS.imperial_teaspoon, BigDecimal.valueOf(5_919_388_020_833_314), UnitGroup.VOLUME, R.string.imperial_teaspoon, R.string.imperial_teaspoon_short),
DefaultUnit(MyUnitIDS.cubic_millimeter, BigDecimal.valueOf(1_000_000_000_000), UnitGroup.VOLUME, R.string.cubic_millimeter, R.string.cubic_millimeter_short),
DefaultUnit(MyUnitIDS.cubic_centimeter, BigDecimal.valueOf(1_000_000_000_000_000), UnitGroup.VOLUME, R.string.cubic_centimeter, R.string.cubic_centimeter_short),
DefaultUnit(MyUnitIDS.cubic_meter, BigDecimal.valueOf(1.0E+21), UnitGroup.VOLUME, R.string.cubic_meter, R.string.cubic_meter_short),
DefaultUnit(MyUnitIDS.cubic_kilometer, BigDecimal.valueOf(1.0E+30), UnitGroup.VOLUME, R.string.cubic_kilometer, R.string.cubic_kilometer_short),
NormalUnit(MyUnitIDS.attoliter, BigDecimal.valueOf(1), UnitGroup.VOLUME, R.string.attoliter, R.string.attoliter_short),
NormalUnit(MyUnitIDS.milliliter, BigDecimal.valueOf(1_000_000_000_000_000), UnitGroup.VOLUME, R.string.milliliter, R.string.milliliter_short),
NormalUnit(MyUnitIDS.liter, BigDecimal.valueOf(1_000_000_000_000_000_000), UnitGroup.VOLUME, R.string.liter, R.string.liter_short),
NormalUnit(MyUnitIDS.us_liquid_gallon, BigDecimal.valueOf(3_785_411_783_999_977_000), UnitGroup.VOLUME, R.string.us_liquid_gallon, R.string.us_liquid_gallon_short),
NormalUnit(MyUnitIDS.us_liquid_quart, BigDecimal.valueOf(946_352_945_999_994_200), UnitGroup.VOLUME, R.string.us_liquid_quart, R.string.us_liquid_quart_short),
NormalUnit(MyUnitIDS.us_liquid_pint, BigDecimal.valueOf(473_176_472_999_997_100), UnitGroup.VOLUME, R.string.us_liquid_pint, R.string.us_liquid_pint_short),
NormalUnit(MyUnitIDS.us_legal_cup, BigDecimal.valueOf(236_588_236_499_998_560), UnitGroup.VOLUME, R.string.us_legal_cup, R.string.us_legal_cup_short),
NormalUnit(MyUnitIDS.us_fluid_ounce, BigDecimal.valueOf(29_573_529_562_499_996), UnitGroup.VOLUME, R.string.us_fluid_ounce, R.string.us_fluid_ounce_short),
NormalUnit(MyUnitIDS.us_tablespoon, BigDecimal.valueOf(14_786_764_781_249_998), UnitGroup.VOLUME, R.string.us_tablespoon, R.string.us_tablespoon_short),
NormalUnit(MyUnitIDS.us_teaspoon, BigDecimal.valueOf(4_928_921_593_749_952), UnitGroup.VOLUME, R.string.us_teaspoon, R.string.us_teaspoon_short),
NormalUnit(MyUnitIDS.imperial_gallon, BigDecimal.valueOf(4_546_089_999_999_954_400), UnitGroup.VOLUME, R.string.imperial_gallon, R.string.imperial_gallon_short),
NormalUnit(MyUnitIDS.imperial_quart, BigDecimal.valueOf(1_136_522_500_000_001_400), UnitGroup.VOLUME, R.string.imperial_quart, R.string.imperial_quart_short),
NormalUnit(MyUnitIDS.imperial_pint, BigDecimal.valueOf(568_261_250_000_000_700), UnitGroup.VOLUME, R.string.imperial_pint, R.string.imperial_pint_short),
NormalUnit(MyUnitIDS.imperial_cup, BigDecimal.valueOf(284_130_625_000_000_350), UnitGroup.VOLUME, R.string.imperial_cup, R.string.imperial_cup_short),
NormalUnit(MyUnitIDS.imperial_fluid_ounce, BigDecimal.valueOf(28_413_062_500_000_036), UnitGroup.VOLUME, R.string.imperial_fluid_ounce, R.string.imperial_fluid_ounce_short),
NormalUnit(MyUnitIDS.imperial_tablespoon, BigDecimal.valueOf(17_758_164_062_500_148), UnitGroup.VOLUME, R.string.imperial_tablespoon, R.string.imperial_tablespoon_short),
NormalUnit(MyUnitIDS.imperial_teaspoon, BigDecimal.valueOf(5_919_388_020_833_314), UnitGroup.VOLUME, R.string.imperial_teaspoon, R.string.imperial_teaspoon_short),
NormalUnit(MyUnitIDS.cubic_millimeter, BigDecimal.valueOf(1_000_000_000_000), UnitGroup.VOLUME, R.string.cubic_millimeter, R.string.cubic_millimeter_short),
NormalUnit(MyUnitIDS.cubic_centimeter, BigDecimal.valueOf(1_000_000_000_000_000), UnitGroup.VOLUME, R.string.cubic_centimeter, R.string.cubic_centimeter_short),
NormalUnit(MyUnitIDS.cubic_meter, BigDecimal.valueOf(1.0E+21), UnitGroup.VOLUME, R.string.cubic_meter, R.string.cubic_meter_short),
NormalUnit(MyUnitIDS.cubic_kilometer, BigDecimal.valueOf(1.0E+30), UnitGroup.VOLUME, R.string.cubic_kilometer, R.string.cubic_kilometer_short),
)
}
}

View File

@ -49,5 +49,5 @@ interface CurrencyApiService {
}
object CurrencyApi {
val retrofitService: CurrencyApiService by lazy { retrofit.create(CurrencyApiService::class.java) }
val service: CurrencyApiService by lazy { retrofit.create(CurrencyApiService::class.java) }
}

View File

@ -1,137 +0,0 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.data.units
import com.sadellie.unitto.data.model.ALL_UNIT_GROUPS
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 {
private val allUnitsRepository = AllUnitsRepository()
private val allUnits: List<AbstractUnit> = ALL_UNIT_GROUPS.flatMap { allUnitsRepository.getCollectionByGroup(it) }
@Test
fun filterAllUnitsNoFiltersLeft() {
// No filters applied, empty search query, from Left side list
val result = allUnitsRepository.filterUnits(
hideBrokenUnits = false,
chosenUnitGroup = null,
favoritesOnly = false,
searchQuery = "",
allUnitsGroups = ALL_UNIT_GROUPS
)
assertEquals(allUnits.groupBy { it.group }, result)
}
@Test
fun filterAllUnitsAllFiltersLeft() {
allUnitsRepository
.getById(MyUnitIDS.kilometer_per_hour)
.apply { isFavorite = true; renderedName = "Kilometer per hour" }
// All filters applied, from Left side list
val result = allUnitsRepository.filterUnits(
hideBrokenUnits = false,
chosenUnitGroup = UnitGroup.SPEED,
favoritesOnly = true,
searchQuery = "kilometer per hour",
allUnitsGroups = ALL_UNIT_GROUPS
)
assertEquals(
mapOf(UnitGroup.SPEED to listOf(allUnitsRepository.getCollectionByGroup(UnitGroup.SPEED)
.first { it.unitId == MyUnitIDS.kilometer_per_hour })),
result
)
}
@Test
fun filterAllUnitsChosenGroupLeft() {
// Only specific group is needed, left side screen
val result = allUnitsRepository.filterUnits(
hideBrokenUnits = false,
chosenUnitGroup = UnitGroup.TIME,
favoritesOnly = false,
searchQuery = "",
allUnitsGroups = ALL_UNIT_GROUPS
)
assertEquals(allUnits.filter { it.group == UnitGroup.TIME }
.groupBy { it.group }, result)
}
@Test
fun filterAllUnitsFavoritesOnlyLeft() {
allUnitsRepository.getById(MyUnitIDS.kilometer).isFavorite = true
// Only favorite units, left side screen
val result = allUnitsRepository.filterUnits(
hideBrokenUnits = false,
chosenUnitGroup = null,
favoritesOnly = true,
searchQuery = "",
allUnitsGroups = ALL_UNIT_GROUPS
)
assertEquals(allUnits.filter { it.unitId == MyUnitIDS.kilometer }
.groupBy { it.group }, result)
}
@Test
fun filterAllUnitsSearchQueryOnlyLeft() {
allUnitsRepository
.getById(MyUnitIDS.kilometer_per_hour)
.apply { renderedName = "Kilometer per hour" }
// Only search query is entered, other filters are not set, left side screen
val result = allUnitsRepository.filterUnits(
hideBrokenUnits = false,
chosenUnitGroup = null,
favoritesOnly = false,
searchQuery = "kilometer per hour",
allUnitsGroups = ALL_UNIT_GROUPS
)
assertEquals(
mapOf(UnitGroup.SPEED to listOf(allUnitsRepository.getCollectionByGroup(UnitGroup.SPEED)
.first { it.unitId == MyUnitIDS.kilometer_per_hour })),
result
)
}
@Test
fun filterAllUnitsHideBrokenCurrencies() {
allUnitsRepository
.getById(MyUnitIDS.currency_btc)
.apply { basicUnit = BigDecimal.ZERO }
// Hide broken currencies (i.e. cannot be used for conversion at the moment)
val result = allUnitsRepository.filterUnits(
hideBrokenUnits = true,
chosenUnitGroup = UnitGroup.CURRENCY,
favoritesOnly = false,
searchQuery = "",
allUnitsGroups = ALL_UNIT_GROUPS
)
assertEquals(
mapOf(UnitGroup.CURRENCY to allUnitsRepository.getCollectionByGroup(UnitGroup.CURRENCY)
.filter { it.unitId != MyUnitIDS.currency_btc }),
result
)
}
}

View File

@ -18,18 +18,32 @@
package com.sadellie.unitto.data.units
import com.sadellie.unitto.data.model.NumberBaseUnit
import android.content.Context
import androidx.room.Room
import com.sadellie.unitto.data.common.setMinimumRequiredScale
import com.sadellie.unitto.data.common.trimZeros
import com.sadellie.unitto.data.database.UnittoDatabase
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 org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import java.math.BigDecimal
@RunWith(RobolectricTestRunner::class)
class AllUnitsTest {
// Group and it's tested unit ids
private var history: MutableMap<UnitGroup, Set<String>> = mutableMapOf()
private val allUnitsRepository = AllUnitsRepository()
private val mContext: Context = RuntimeEnvironment.getApplication().applicationContext
private val allUnitsRepository = UnitsRepository(
Room.inMemoryDatabaseBuilder(mContext, UnittoDatabase::class.java).build().unitsDao(),
mContext
)
@Test
fun testAcceleration() = testWithUnits {
@ -514,12 +528,17 @@ class AllUnitsTest {
val unitFrom = allUnitsRepository.getById(this)
val unitTo = allUnitsRepository.getById(checkingId)
val actual = if (unitFrom.group == UnitGroup.NUMBER_BASE) {
(unitFrom as NumberBaseUnit)
.convertToBase(value, (unitTo as NumberBaseUnit).base)
} else {
unitFrom
.convert(unitTo, BigDecimal(value), 5)
val actual = when (unitFrom.group) {
UnitGroup.NUMBER_BASE -> (unitFrom as NumberBaseUnit).convert((unitTo as NumberBaseUnit), value)
UnitGroup.FLOW_RATE -> (unitFrom as ReverseUnit)
.convert((unitTo as DefaultUnit), BigDecimal(value))
.setMinimumRequiredScale(5)
.trimZeros()
.toPlainString()
else -> (unitFrom as DefaultUnit)
.convert((unitTo as DefaultUnit), BigDecimal(value))
.setMinimumRequiredScale(5)
.trimZeros()
.toPlainString()
}
assertEquals("Failed at $this to $checkingId", expected, actual)
@ -532,7 +551,7 @@ class AllUnitsTest {
fun after() {
val unitGroup = history.keys.first()
// GROUP : testedCount / totalCount
println("${unitGroup.name} : ${history[unitGroup]?.size} / ${allUnitsRepository.getCollectionByGroup(unitGroup).size}")
println("${unitGroup.name} : ${history[unitGroup]?.size} / ${allUnitsRepository.getCollection(unitGroup).size}")
}
private fun testWithUnits(block: MyUnitIDS.() -> Unit): Unit = with(MyUnitIDS, block = block)

View File

@ -18,34 +18,38 @@
package com.sadellie.unitto.data.units
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.DefaultUnit
import android.content.Context
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.sortByLev
import com.sadellie.unitto.data.model.unit.NormalUnit
import com.sadellie.unitto.data.model.unit.filterByLev
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import java.math.BigDecimal
val baseList: List<AbstractUnit> = listOf(
"Attometer",
"Nanometer",
"Millimeter",
"Meter",
"Kilometer",
"Mile",
"Pound",
"Kilometer per square"
).map { name ->
DefaultUnit("", BigDecimal.ONE, UnitGroup.ANGLE, 0, 0)
.also { it.renderedName = name }
}
val baseList = listOf(
NormalUnit("", BigDecimal.ONE, UnitGroup.ANGLE, R.string.attometer, R.string.attometer_short),
NormalUnit("", BigDecimal.ONE, UnitGroup.ANGLE, R.string.nanometer, R.string.nanometer_short),
NormalUnit("", BigDecimal.ONE, UnitGroup.ANGLE, R.string.millimeter, R.string.millimeter_short),
NormalUnit("", BigDecimal.ONE, UnitGroup.ANGLE, R.string.meter, R.string.meter_short),
NormalUnit("", BigDecimal.ONE, UnitGroup.ANGLE, R.string.kilometer, R.string.kilometer_short),
NormalUnit("", BigDecimal.ONE, UnitGroup.ANGLE, R.string.mile, R.string.mile_short),
NormalUnit("", BigDecimal.ONE, UnitGroup.ANGLE, R.string.pound, R.string.pound_short),
NormalUnit("", BigDecimal.ONE, UnitGroup.ANGLE, R.string.kilometer_per_square_second, R.string.kilometer_per_square_second_short),
)
@RunWith(RobolectricTestRunner::class)
class LevenshteinFilterAndSortTest {
private val mContext: Context = RuntimeEnvironment.getApplication().applicationContext
@Test
fun testOneEdit() {
val searchQuery = "Kelometer"
val result = baseList.asSequence().sortByLev(searchQuery).map { it.renderedName }.toList()
val result = baseList.asSequence().filterByLev(searchQuery, mContext).map { mContext.getString(it.displayName) }.toList()
println(result)
assertEquals(
listOf("Kilometer", "Kilometer per square", "Attometer", "Nanometer"),
@ -56,7 +60,7 @@ class LevenshteinFilterAndSortTest {
@Test
fun testLongQuery() {
val searchQuery = "Kelometers per"
val result = baseList.asSequence().sortByLev(searchQuery).map { it.renderedName }.toList()
val result = baseList.asSequence().filterByLev(searchQuery, mContext).map { mContext.getString(it.displayName) }.toList()
println(result)
assertEquals(
listOf("Kilometer per square", "Kilometer"),
@ -67,7 +71,7 @@ class LevenshteinFilterAndSortTest {
@Test
fun testMultipleMatches() {
val searchQuery = "meter"
val result = baseList.asSequence().sortByLev(searchQuery).map { it.renderedName }.toList()
val result = baseList.asSequence().filterByLev(searchQuery, mContext).map { mContext.getString(it.displayName) }.toList()
println(result)
assertEquals(
listOf("Meter", "Attometer", "Nanometer", "Millimeter", "Kilometer","Kilometer per square"),
@ -78,7 +82,7 @@ class LevenshteinFilterAndSortTest {
@Test
fun testNone() {
val searchQuery = "Very long unit name that doesn't exist"
val result = baseList.asSequence().sortByLev(searchQuery).map { it.renderedName }.toList()
val result = baseList.asSequence().filterByLev(searchQuery, mContext).map { mContext.getString(it.displayName) }.toList()
println(result)
assertEquals(
listOf<String>(),
@ -89,7 +93,7 @@ class LevenshteinFilterAndSortTest {
@Test
fun testLowerAndUpperCases() {
val searchQuery = "T"
val result = baseList.asSequence().sortByLev(searchQuery).map { it.renderedName }.toList()
val result = baseList.asSequence().filterByLev(searchQuery, mContext).map { mContext.getString(it.displayName) }.toList()
println(result)
assertEquals(
listOf("Attometer", "Nanometer", "Millimeter", "Meter", "Kilometer", "Kilometer per square"),

View File

@ -31,9 +31,9 @@ import com.sadellie.unitto.core.base.OutputFormat
import com.sadellie.unitto.core.base.Separator
import com.sadellie.unitto.core.base.TopLevelDestinations
import com.sadellie.unitto.data.model.ALL_UNIT_GROUPS
import com.sadellie.unitto.data.model.AbstractUnit
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.units.MyUnitIDS
import io.github.sadellie.themmo.MonetMode
import io.github.sadellie.themmo.ThemingMode
@ -175,7 +175,7 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
)
}
val mainPreferencesFlow: Flow<MainPreferences> = dataStore.data
val mainPrefsFlow: Flow<MainPreferences> = dataStore.data
.catch { exception ->
if (exception is IOException) {
emit(emptyPreferences())
@ -226,7 +226,7 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
}
val allPreferencesFlow = combine(
mainPreferencesFlow, uiPreferencesFlow
mainPrefsFlow, uiPreferencesFlow
) { main, ui ->
return@combine UserPreferences(
themingMode = ui.themingMode,
@ -285,17 +285,10 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
}
}
/**
* Update latest used pair of [AbstractUnit] in DataStore. Need it so when user restarts the app,
* this pair will be already set.
*
* @param leftSideUnit [AbstractUnit] on the left
* @param rightSideUnit [AbstractUnit] on the right
*/
suspend fun updateLatestPairOfUnits(leftSideUnit: AbstractUnit, rightSideUnit: AbstractUnit) {
suspend fun updateLatestPairOfUnits(unitFrom: AbstractUnit, unitTo: AbstractUnit) {
dataStore.edit { preferences ->
preferences[PrefsKeys.LATEST_LEFT_SIDE] = leftSideUnit.unitId
preferences[PrefsKeys.LATEST_RIGHT_SIDE] = rightSideUnit.unitId
preferences[PrefsKeys.LATEST_LEFT_SIDE] = unitFrom.id
preferences[PrefsKeys.LATEST_RIGHT_SIDE] = unitTo.id
}
}

View File

@ -55,7 +55,7 @@ internal class CalculatorViewModel @Inject constructor(
private val calculatorHistoryRepository: CalculatorHistoryRepository,
) : ViewModel() {
private val _userPrefs: StateFlow<MainPreferences> =
userPrefsRepository.mainPreferencesFlow.stateIn(
userPrefsRepository.mainPrefsFlow.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5000L),
MainPreferences()

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
@file:Suppress("UnstableApiUsage")
plugins {
id("unitto.library")
id("unitto.library.compose")
@ -25,10 +27,13 @@ plugins {
android {
namespace = "com.sadellie.unitto.feature.converter"
testOptions.unitTests.isIncludeAndroidResources = true
}
dependencies {
testImplementation(libs.junit)
testImplementation(libs.org.robolectric)
testImplementation(libs.org.jetbrains.kotlinx.coroutines.test)
testImplementation(libs.androidx.room.runtime)
testImplementation(libs.androidx.room.ktx)

View File

@ -18,36 +18,73 @@
package com.sadellie.unitto.feature.converter
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.SizeTransform
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandHorizontally
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.SwapHoriz
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.sadellie.unitto.core.base.OutputFormat
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.core.base.Token
import com.sadellie.unitto.core.ui.common.ColumnWithConstraints
import com.sadellie.unitto.core.ui.common.MenuButton
import com.sadellie.unitto.core.ui.common.PortraitLandscape
import com.sadellie.unitto.core.ui.common.SettingsButton
import com.sadellie.unitto.core.ui.common.UnittoScreenWithTopBar
import com.sadellie.unitto.feature.converter.components.ConverterKeyboard
import com.sadellie.unitto.feature.converter.components.TopScreenPart
import com.sadellie.unitto.core.ui.common.textfield.ExpressionTextField
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
import com.sadellie.unitto.core.ui.common.textfield.UnformattedTextField
import com.sadellie.unitto.data.common.format
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.feature.converter.components.DefaultKeyboard
import com.sadellie.unitto.feature.converter.components.LoadingKeyboard
import com.sadellie.unitto.feature.converter.components.NumberBaseKeyboard
import com.sadellie.unitto.feature.converter.components.UnitSelectionButton
@Composable
internal fun ConverterRoute(
viewModel: ConverterViewModel = hiltViewModel(),
navigateToLeftScreen: (String) -> Unit,
navigateToRightScreen: (unitFrom: String, unitTo: String, input: String?) -> Unit,
navigateToLeftScreen: () -> Unit,
navigateToRightScreen: () -> Unit,
navigateToMenu: () -> Unit,
navigateToSettings: () -> Unit
navigateToSettings: () -> Unit,
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle()
val uiState = viewModel.converterUiState.collectAsStateWithLifecycle()
ConverterScreen(
uiState = uiState.value,
@ -55,30 +92,28 @@ internal fun ConverterRoute(
navigateToRightScreen = navigateToRightScreen,
navigateToSettings = navigateToSettings,
navigateToMenu = navigateToMenu,
swapMeasurements = viewModel::swapUnits,
swapUnits = viewModel::swapUnits,
processInput = viewModel::addTokens,
deleteDigit = viewModel::deleteTokens,
clearInput = viewModel::clearInput,
onCursorChange = viewModel::onCursorChange,
cutCallback = viewModel::deleteTokens,
onErrorClick = viewModel::updateCurrenciesRatesIfNeeded,
onErrorClick = viewModel::updateCurrencyRates,
)
}
@Composable
private fun ConverterScreen(
uiState: ConverterUIState,
navigateToLeftScreen: (String) -> Unit,
navigateToRightScreen: (unitFrom: String, unitTo: String, input: String?) -> Unit,
uiState: UnitConverterUIState,
navigateToLeftScreen: () -> Unit,
navigateToRightScreen: () -> Unit,
navigateToSettings: () -> Unit,
navigateToMenu: () -> Unit,
swapMeasurements: () -> Unit,
swapUnits: () -> Unit,
processInput: (String) -> Unit,
deleteDigit: () -> Unit,
clearInput: () -> Unit,
onCursorChange: (TextRange) -> Unit,
cutCallback: () -> Unit,
onErrorClick: () -> Unit,
onErrorClick: (AbstractUnit) -> Unit,
) {
UnittoScreenWithTopBar(
title = { Text(stringResource(R.string.unit_converter)) },
@ -89,46 +124,358 @@ private fun ConverterScreen(
colors = TopAppBarDefaults
.centerAlignedTopAppBarColors(containerColor = Color.Transparent),
content = { padding ->
PortraitLandscape(
modifier = Modifier
.padding(padding)
.fillMaxSize(),
content1 = {
TopScreenPart(
modifier = it,
inputValue = uiState.inputValue,
calculatedValue = uiState.calculatedValue,
outputValue = uiState.resultValue,
unitFrom = uiState.unitFrom,
unitTo = uiState.unitTo,
navigateToLeftScreen = navigateToLeftScreen,
navigateToRightScreen = navigateToRightScreen,
swapUnits = swapMeasurements,
converterMode = uiState.mode,
when (uiState) {
is UnitConverterUIState.Loading -> {
ConverterLoading(modifier = Modifier.padding(padding))
}
is UnitConverterUIState.NumberBase -> {
NumberBase(
modifier = Modifier.padding(padding),
uiState = uiState,
onCursorChange = onCursorChange,
cutCallback = cutCallback,
pasteCallback = processInput,
formatterSymbols = uiState.formatterSymbols,
onErrorClick = onErrorClick
)
},
content2 = {
ConverterKeyboard(
modifier = it,
addDigit = processInput,
processInput = processInput,
deleteDigit = deleteDigit,
clearInput = clearInput,
converterMode = uiState.mode,
allowVibration = uiState.allowVibration,
fractional = uiState.formatterSymbols.fractional,
middleZero = uiState.middleZero
navigateToLeftScreen = navigateToLeftScreen,
swapUnits = swapUnits,
navigateToRightScreen = navigateToRightScreen,
clearInput = clearInput
)
}
is UnitConverterUIState.Default -> {
Default(
modifier = Modifier.padding(padding),
uiState = uiState,
onCursorChange = onCursorChange,
processInput = processInput,
deleteDigit = deleteDigit,
navigateToLeftScreen = navigateToLeftScreen,
swapUnits = swapUnits,
navigateToRightScreen = navigateToRightScreen,
clearInput = clearInput,
refreshCurrencyRates = onErrorClick
)
}
}
}
)
}
@Composable
private fun ConverterLoading(modifier: Modifier) {
PortraitLandscape(
modifier = modifier.fillMaxSize(),
content1 = { contentModifier ->
ColumnWithConstraints(modifier = contentModifier) {
val textFieldModifier = Modifier.weight(2f)
UnformattedTextField(
modifier = textFieldModifier,
value = TextFieldValue(stringResource(R.string.loading_label)),
onCursorChange = {},
minRatio = 0.7f,
readOnly = true
)
AnimatedUnitShortName()
ConverterResultTextField(
modifier = textFieldModifier,
result = ConverterResult.Loading
)
AnimatedUnitShortName()
Spacer(modifier = Modifier.height(it.maxHeight * 0.03f))
UnitSelectionButtons()
}
},
content2 = {
LoadingKeyboard(modifier = it)
}
)
}
@Composable
private fun NumberBase(
modifier: Modifier,
uiState: UnitConverterUIState.NumberBase,
onCursorChange: (TextRange) -> Unit,
processInput: (String) -> Unit,
deleteDigit: () -> Unit,
navigateToLeftScreen: () -> Unit,
swapUnits: () -> Unit,
navigateToRightScreen: () -> Unit,
clearInput: () -> Unit,
) {
PortraitLandscape(
modifier = modifier.fillMaxSize(),
content1 = { contentModifier ->
ColumnWithConstraints(modifier = contentModifier) {
val textFieldModifier = Modifier.weight(2f)
UnformattedTextField(
modifier = textFieldModifier,
minRatio = 0.7f,
placeholder = Token.Digit._0,
value = uiState.input,
onCursorChange = onCursorChange,
pasteCallback = processInput,
cutCallback = deleteDigit,
)
AnimatedUnitShortName(stringResource(uiState.unitFrom.shortName))
ConverterResultTextField(
modifier = textFieldModifier,
result = uiState.result
)
AnimatedUnitShortName(stringResource(uiState.unitTo.shortName))
Spacer(modifier = Modifier.height(it.maxHeight * 0.03f))
UnitSelectionButtons(
unitFromLabel = stringResource(uiState.unitFrom.displayName),
unitToLabel = stringResource(uiState.unitTo.displayName),
swapUnits = swapUnits,
navigateToLeftScreen = navigateToLeftScreen,
navigateToRightScreen = navigateToRightScreen
)
}
},
content2 = {
NumberBaseKeyboard(
modifier = it,
addDigit = processInput,
deleteDigit = deleteDigit,
clearInput = clearInput,
allowVibration = uiState.enableHaptic,
)
}
)
}
@Composable
private fun Default(
modifier: Modifier,
uiState: UnitConverterUIState.Default,
onCursorChange: (TextRange) -> Unit,
processInput: (String) -> Unit,
deleteDigit: () -> Unit,
navigateToLeftScreen: () -> Unit,
swapUnits: () -> Unit,
navigateToRightScreen: () -> Unit,
clearInput: () -> Unit,
refreshCurrencyRates: (AbstractUnit) -> Unit,
) {
var calculation by remember(uiState.calculation) {
mutableStateOf(
TextFieldValue(uiState.calculation?.format(uiState.scale, uiState.outputFormat) ?: "")
)
}
PortraitLandscape(
modifier = modifier.fillMaxSize(),
content1 = { contentModifier ->
ColumnWithConstraints(modifier = contentModifier) {
val textFieldModifier = Modifier.weight(2f)
ExpressionTextField(
modifier = textFieldModifier,
minRatio = 0.7f,
placeholder = Token.Digit._0,
value = uiState.input,
onCursorChange = onCursorChange,
pasteCallback = processInput,
cutCallback = deleteDigit,
formatterSymbols = uiState.formatterSymbols,
)
AnimatedVisibility(
visible = uiState.calculation != null,
modifier = Modifier.weight(1f)
) {
ExpressionTextField(
modifier = Modifier,
value = calculation,
onCursorChange = { calculation = calculation.copy(selection = it) },
formatterSymbols = uiState.formatterSymbols,
minRatio = 0.7f,
textColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f),
readOnly = true
)
}
AnimatedUnitShortName(stringResource(uiState.unitFrom.shortName))
ConverterResultTextField(
modifier = textFieldModifier,
result = uiState.result,
scale = uiState.scale,
outputFormat = uiState.outputFormat,
formatterSymbols = uiState.formatterSymbols,
onErrorClick = { refreshCurrencyRates(uiState.unitFrom) }
)
AnimatedUnitShortName(
stringResource(
if (uiState.result is ConverterResult.Error) R.string.try_again_label
else uiState.unitTo.shortName
)
)
Spacer(modifier = Modifier.height(it.maxHeight * 0.03f))
UnitSelectionButtons(
unitFromLabel = stringResource(uiState.unitFrom.displayName),
unitToLabel = stringResource(uiState.unitTo.displayName),
swapUnits = swapUnits,
navigateToLeftScreen = navigateToLeftScreen,
navigateToRightScreen = navigateToRightScreen
)
}
},
content2 = {
DefaultKeyboard(
modifier = it,
addDigit = processInput,
deleteDigit = deleteDigit,
clearInput = clearInput,
allowVibration = uiState.enableHaptic,
fractional = uiState.formatterSymbols.fractional,
middleZero = uiState.middleZero
)
}
)
}
@Composable
private fun ConverterResultTextField(
modifier: Modifier,
result: ConverterResult,
scale: Int = 0,
outputFormat: Int = OutputFormat.PLAIN,
formatterSymbols: FormatterSymbols = FormatterSymbols.Spaces,
onErrorClick: () -> Unit = {},
) {
val mContext = LocalContext.current
var resultTextField by remember(result) {
val value = when (result) {
is ConverterResult.Default -> result.value.format(scale, outputFormat)
is ConverterResult.NumberBase -> result.value.uppercase()
is ConverterResult.Time -> result.format(mContext, formatterSymbols)
else -> ""
}
mutableStateOf(TextFieldValue(value))
}
when (result) {
is ConverterResult.Loading -> {
UnformattedTextField(
modifier = modifier,
value = TextFieldValue(stringResource(R.string.loading_label)),
onCursorChange = {},
minRatio = 0.7f,
readOnly = true
)
}
is ConverterResult.Error -> {
UnformattedTextField(
modifier = modifier,
value = TextFieldValue(stringResource(R.string.error_label)),
onCursorChange = { onErrorClick() },
minRatio = 0.7f,
readOnly = true,
textColor = MaterialTheme.colorScheme.error,
)
}
is ConverterResult.Default -> {
ExpressionTextField(
modifier = modifier,
value = resultTextField,
onCursorChange = { resultTextField = resultTextField.copy(selection = it) },
formatterSymbols = formatterSymbols,
minRatio = 0.7f,
readOnly = true
)
}
is ConverterResult.NumberBase, is ConverterResult.Time -> {
UnformattedTextField(
modifier = modifier,
value = resultTextField,
onCursorChange = { resultTextField = resultTextField.copy(selection = it) },
minRatio = 0.7f,
readOnly = true
)
}
}
}
@Composable
private fun AnimatedUnitShortName(
label: String = stringResource(R.string.loading_label),
) {
AnimatedContent(
modifier = Modifier.fillMaxWidth(),
targetState = label,
transitionSpec = {
// Enter animation
(expandHorizontally(clip = false, expandFrom = Alignment.Start) + fadeIn()
togetherWith fadeOut()) using SizeTransform(clip = false)
},
label = "Animated short name from"
) { value ->
Text(
text = value,
style = MaterialTheme.typography.bodyMedium.copy(textAlign = TextAlign.End)
)
}
}
@Composable
private fun UnitSelectionButtons(
unitFromLabel: String = stringResource(R.string.loading_label),
unitToLabel: String = stringResource(R.string.loading_label),
swapUnits: () -> Unit = {},
navigateToLeftScreen: () -> Unit = {},
navigateToRightScreen: () -> Unit = {},
) {
var swapped by remember { mutableStateOf(false) }
val swapButtonRotation: Float by animateFloatAsState(
targetValue = if (swapped) 0f else 180f,
animationSpec = tween(easing = FastOutSlowInEasing),
label = "Swap button rotation"
)
Row(verticalAlignment = Alignment.CenterVertically) {
UnitSelectionButton(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
label = unitFromLabel,
onClick = navigateToLeftScreen
)
IconButton(
onClick = {
swapUnits()
swapped = !swapped
},
) {
Icon(
modifier = Modifier.rotate(swapButtonRotation),
imageVector = Icons.Outlined.SwapHoriz,
contentDescription = stringResource(R.string.swap_units_description)
)
}
UnitSelectionButton(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
label = unitToLabel,
onClick = navigateToRightScreen
)
}
}
@Preview(widthDp = 432, heightDp = 1008, device = "spec:parent=pixel_5,orientation=portrait")
@Preview(widthDp = 432, heightDp = 864, device = "spec:parent=pixel_5,orientation=portrait")
@Preview(widthDp = 597, heightDp = 1393, device = "spec:parent=pixel_5,orientation=portrait")
@ -138,17 +485,16 @@ private fun ConverterScreen(
@Composable
private fun PreviewConverterScreen() {
ConverterScreen(
uiState = ConverterUIState(inputValue = TextFieldValue("1234"), calculatedValue = null, resultValue = ConversionResult.Default("5678"), showLoading = false),
uiState = UnitConverterUIState.Loading,
navigateToLeftScreen = {},
navigateToRightScreen = {_, _, _ -> },
navigateToRightScreen = {},
navigateToSettings = {},
navigateToMenu = {},
swapMeasurements = {},
swapUnits = {},
processInput = {},
deleteDigit = {},
clearInput = {},
onCursorChange = {},
cutCallback = {},
onErrorClick = {},
)
}

View File

@ -18,48 +18,183 @@
package com.sadellie.unitto.feature.converter
import android.content.Context
import androidx.compose.ui.text.input.TextFieldValue
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.core.base.Token
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
import com.sadellie.unitto.data.common.trimZeros
import com.sadellie.unitto.data.model.unit.DefaultUnit
import com.sadellie.unitto.data.model.unit.NumberBaseUnit
import java.math.BigDecimal
import java.math.RoundingMode
/**
* Represents current state of the ConverterScreen
*
* @property inputValue Current input value. Can be expression or a simple number.
* @property calculatedValue Currently calculated value. Can be null if not needed (same as input or
* expression in input is invalid).
* @property resultValue Current output value.
* @property showLoading Whether we are loading data from network.
* @property showError Whether there was an error while loading data from network
* @property unitFrom Unit on the left.
* @property unitTo Unit on the right.
* @property mode
* @property allowVibration When true will vibrate on button clicks.
*/
data class ConverterUIState(
val inputValue: TextFieldValue = TextFieldValue(),
val calculatedValue: String? = null,
val resultValue: ConversionResult = ConversionResult.Default(Token.Digit._0),
val showLoading: Boolean = true,
val showError: Boolean = false,
val unitFrom: AbstractUnit? = null,
val unitTo: AbstractUnit? = null,
val mode: ConverterMode = ConverterMode.DEFAULT,
val allowVibration: Boolean = false,
val middleZero: Boolean = false,
val formatterSymbols: FormatterSymbols = FormatterSymbols.Spaces,
)
internal sealed class UnitConverterUIState {
data object Loading : UnitConverterUIState()
enum class ConverterMode {
DEFAULT,
BASE,
data class Default(
val input: TextFieldValue = TextFieldValue(),
val calculation: BigDecimal?,
val result: ConverterResult,
val unitFrom: DefaultUnit,
val unitTo: DefaultUnit,
val enableHaptic: Boolean,
val middleZero: Boolean,
val formatterSymbols: FormatterSymbols,
val scale: Int,
val outputFormat: Int,
val formatTime: Boolean,
) : UnitConverterUIState()
data class NumberBase(
val input: TextFieldValue = TextFieldValue(),
val result: ConverterResult,
val unitFrom: NumberBaseUnit,
val unitTo: NumberBaseUnit,
val enableHaptic: Boolean,
) : UnitConverterUIState()
}
sealed class ConversionResult {
data class Default(val result: String) : ConversionResult()
data class Time(val result: String) : ConversionResult()
data class NumberBase(val result: String) : ConversionResult()
data object Loading : ConversionResult()
data object Error : ConversionResult()
internal sealed class ConverterResult {
data class Default(val value: BigDecimal) : ConverterResult()
data class NumberBase(val value: String) : ConverterResult()
data class Time(
val negative: Boolean,
val day: BigDecimal,
val hour: BigDecimal,
val minute: BigDecimal,
val second: BigDecimal,
val millisecond: BigDecimal,
val microsecond: BigDecimal,
val nanosecond: BigDecimal,
val attosecond: BigDecimal,
) : ConverterResult()
data object Loading : ConverterResult()
data object Error : ConverterResult()
}
internal fun ConverterResult.Time.format(mContext: Context, formatterSymbols: FormatterSymbols): String {
val result = mutableListOf<String>()
if (day.compareTo(BigDecimal.ZERO) == 1) {
result += "${day.toPlainString().formatExpression(formatterSymbols)}${mContext.getString(R.string.day_short)}"
}
if (hour.compareTo(BigDecimal.ZERO) == 1) {
result += "${hour.toPlainString().formatExpression(formatterSymbols)}${mContext.getString(R.string.hour_short)}"
}
if (minute.compareTo(BigDecimal.ZERO) == 1) {
result += "${minute.toPlainString().formatExpression(formatterSymbols)}${mContext.getString(R.string.minute_short)}"
}
if (second.compareTo(BigDecimal.ZERO) == 1) {
result += "${second.toPlainString().formatExpression(formatterSymbols)}${mContext.getString(R.string.second_short)}"
}
if (millisecond.compareTo(BigDecimal.ZERO) == 1) {
result += "${millisecond.toPlainString().formatExpression(formatterSymbols)}${mContext.getString(R.string.millisecond_short)}"
}
if (microsecond.compareTo(BigDecimal.ZERO) == 1) {
result += "${microsecond.toPlainString().formatExpression(formatterSymbols)}${mContext.getString(R.string.microsecond_short)}"
}
if (nanosecond.compareTo(BigDecimal.ZERO) == 1) {
result += "${nanosecond.toPlainString().formatExpression(formatterSymbols)}${mContext.getString(R.string.nanosecond_short)}"
}
if (attosecond.compareTo(BigDecimal.ZERO) == 1) {
result += "${attosecond.toPlainString().formatExpression(formatterSymbols)}${mContext.getString(R.string.attosecond_short)}"
}
return (if (negative) Token.Operator.minus else "") + result.joinToString(" ").ifEmpty { Token.Digit._0 }
}
internal fun formatTime(
input: BigDecimal,
): ConverterResult.Time {
val negative = input < BigDecimal.ZERO
val inputAbs = input.abs()
if (inputAbs.compareTo(attosecondBasicUnit) == -1) return ConverterResult.Time(
negative = negative,
day = BigDecimal.ZERO,
hour = BigDecimal.ZERO,
minute = BigDecimal.ZERO,
second = BigDecimal.ZERO,
millisecond = BigDecimal.ZERO,
microsecond = BigDecimal.ZERO,
nanosecond = BigDecimal.ZERO,
attosecond = inputAbs
)
if (inputAbs.compareTo(nanosecondBasicUnit) == -1) return ConverterResult.Time(
negative = negative,
day = BigDecimal.ZERO,
hour = BigDecimal.ZERO,
minute = BigDecimal.ZERO,
second = BigDecimal.ZERO,
millisecond = BigDecimal.ZERO,
microsecond = BigDecimal.ZERO,
nanosecond = BigDecimal.ZERO,
attosecond = inputAbs.trimZeros()
)
// DAY
var division = inputAbs.divideAndRemainder(dayBasicUnit)
val day = division.component1().setScale(0, RoundingMode.HALF_EVEN)
var remainingSeconds = division.component2().setScale(0, RoundingMode.HALF_EVEN)
division = remainingSeconds.divideAndRemainder(hourBasicUnit)
val hour = division.component1()
remainingSeconds = division.component2()
division = remainingSeconds.divideAndRemainder(minuteBasicUnit)
val minute = division.component1()
remainingSeconds = division.component2()
division = remainingSeconds.divideAndRemainder(secondBasicUnit)
val second = division.component1()
remainingSeconds = division.component2()
division = remainingSeconds.divideAndRemainder(millisecondBasicUnit)
val millisecond = division.component1()
remainingSeconds = division.component2()
division = remainingSeconds.divideAndRemainder(microsecondBasicUnit)
val microsecond = division.component1()
remainingSeconds = division.component2()
division = remainingSeconds.divideAndRemainder(nanosecondBasicUnit)
val nanosecond = division.component1()
remainingSeconds = division.component2()
val attosecond = remainingSeconds
return ConverterResult.Time(
negative = negative,
day = day,
hour = hour,
minute = minute,
second = second,
millisecond = millisecond,
microsecond = microsecond,
nanosecond = nanosecond,
attosecond = attosecond
)
}
private val dayBasicUnit by lazy { BigDecimal("86400000000000000000000") }
private val hourBasicUnit by lazy { BigDecimal("3600000000000000000000") }
private val minuteBasicUnit by lazy { BigDecimal("60000000000000000000") }
private val secondBasicUnit by lazy { BigDecimal("1000000000000000000") }
private val millisecondBasicUnit by lazy { BigDecimal("1000000000000000") }
private val microsecondBasicUnit by lazy { BigDecimal("1000000000000") }
private val nanosecondBasicUnit by lazy { BigDecimal("1000000000") }
private val attosecondBasicUnit by lazy { BigDecimal("1") }

View File

@ -22,34 +22,31 @@ import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.TextFieldValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sadellie.unitto.core.base.Token
import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols
import com.sadellie.unitto.core.ui.common.textfield.addTokens
import com.sadellie.unitto.core.ui.common.textfield.deleteTokens
import com.sadellie.unitto.data.common.isExpression
import com.sadellie.unitto.data.common.setMinimumRequiredScale
import com.sadellie.unitto.data.common.toStringWith
import com.sadellie.unitto.data.common.trimZeros
import com.sadellie.unitto.data.database.UnitsEntity
import com.sadellie.unitto.data.database.UnitsRepository
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.NumberBaseUnit
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.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.NumberBaseUnit
import com.sadellie.unitto.data.units.UnitsRepository
import com.sadellie.unitto.data.units.combine
import com.sadellie.unitto.data.userprefs.MainPreferences
import com.sadellie.unitto.data.units.stateIn
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import io.github.sadellie.evaluatto.Expression
import io.github.sadellie.evaluatto.ExpressionException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.getAndUpdate
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
@ -57,306 +54,345 @@ import java.math.BigDecimal
import javax.inject.Inject
@HiltViewModel
class ConverterViewModel @Inject constructor(
internal class ConverterViewModel @Inject constructor(
private val userPrefsRepository: UserPreferencesRepository,
private val unitRepository: UnitsRepository,
private val allUnitsRepository: AllUnitsRepository
private val unitsRepo: UnitsRepository,
) : ViewModel() {
private val _userPrefs = userPrefsRepository.mainPreferencesFlow.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5000),
MainPreferences()
)
enum class CurrencyRateUpdateState { READY, LOADING, ERROR }
/**
* Unit on the left, the one we convert from. Initially null, meaning we didn't restore it yet.
*/
private val _unitFrom: MutableStateFlow<AbstractUnit?> = MutableStateFlow(null)
private val _input = MutableStateFlow(TextFieldValue())
private val _calculation = MutableStateFlow<BigDecimal?>(null)
private val _result = MutableStateFlow<ConverterResult>(ConverterResult.Loading)
private val _unitFrom = MutableStateFlow<AbstractUnit?>(null)
private val _unitTo = MutableStateFlow<AbstractUnit?>(null)
/**
* Unit on the right, the one we convert to. Initially null, meaning we didn't restore it yet.
*/
private val _unitTo: MutableStateFlow<AbstractUnit?> = MutableStateFlow(null)
private val _leftSideUIState = MutableStateFlow(LeftSideUIState())
private val _rightSideUIState = MutableStateFlow(RightSideUIState())
private val _loadingCurrencies = MutableStateFlow(CurrencyRateUpdateState.READY)
private var _loadCurrenciesJob: Job? = null
private val _input: MutableStateFlow<TextFieldValue> = MutableStateFlow(TextFieldValue())
/**
* Calculation result. Null when [_input] is not an expression.
*/
private val _calculated: MutableStateFlow<String?> = MutableStateFlow(null)
/**
* Conversion result.
*/
private val _result: MutableStateFlow<ConversionResult> = MutableStateFlow(ConversionResult.Loading)
/**
* True when loading something from network.
*/
private val _showLoading: MutableStateFlow<Boolean> = MutableStateFlow(false)
/**
* True if there was error while loading data.
*/
private val _showError: MutableStateFlow<Boolean> = MutableStateFlow(false)
/**
* Current state of UI.
*/
val uiState: StateFlow<ConverterUIState> = combine(
val converterUiState: StateFlow<UnitConverterUIState> = combine(
_input,
_calculation,
_result,
_unitFrom,
_unitTo,
_calculated,
_result,
_userPrefs,
_showError,
_showLoading
) { inputValue, unitFromValue, unitToValue, calculatedValue, resultValue, prefs, showError, showLoading ->
return@combine ConverterUIState(
inputValue = inputValue,
calculatedValue = calculatedValue,
resultValue = when {
showError -> ConversionResult.Error
showLoading -> ConversionResult.Loading
else -> resultValue
},
unitFrom = unitFromValue,
unitTo = unitToValue,
mode = if (_unitFrom.value is NumberBaseUnit) ConverterMode.BASE else ConverterMode.DEFAULT,
allowVibration = prefs.enableVibrations,
formatterSymbols = AllFormatterSymbols.getById(prefs.separator),
middleZero = prefs.middleZero,
userPrefsRepository.mainPrefsFlow,
_loadingCurrencies
) { input, calculation, result, unitFrom, unitTo, prefs, _ ->
return@combine when {
(unitFrom is DefaultUnit) and (unitTo is DefaultUnit) -> {
UnitConverterUIState.Default(
input = input,
calculation = calculation,
result = result,
unitFrom = unitFrom as DefaultUnit,
unitTo = unitTo as DefaultUnit,
enableHaptic = prefs.enableVibrations,
middleZero = prefs.middleZero,
formatterSymbols = AllFormatterSymbols.getById(prefs.separator),
scale = prefs.digitsPrecision,
outputFormat = prefs.outputFormat,
formatTime = prefs.unitConverterFormatTime,
)
}
(unitFrom is NumberBaseUnit) and (unitTo is NumberBaseUnit) -> {
UnitConverterUIState.NumberBase(
input = input,
result = result,
unitFrom = unitFrom as NumberBaseUnit,
unitTo = unitTo as NumberBaseUnit,
enableHaptic = prefs.enableVibrations,
)
}
else -> UnitConverterUIState.Loading
}
}
.onEach { ui ->
when (_loadingCurrencies.value) {
CurrencyRateUpdateState.LOADING -> {
_result.update { ConverterResult.Loading }
return@onEach
}
CurrencyRateUpdateState.ERROR -> {
_result.update { ConverterResult.Error }
return@onEach
}
CurrencyRateUpdateState.READY -> {}
}
when (ui) {
is UnitConverterUIState.Default -> {
convertDefault(
unitFrom = ui.unitFrom,
unitTo = ui.unitTo,
input = ui.input,
formatTime = ui.formatTime
)
}
is UnitConverterUIState.NumberBase -> {
convertNumberBase(
unitFrom = ui.unitFrom,
unitTo = ui.unitTo,
input = ui.input
)
}
is UnitConverterUIState.Loading -> {}
}
}
.stateIn(viewModelScope, UnitConverterUIState.Loading)
val leftSideUIState = combine(
_unitFrom,
_leftSideUIState,
userPrefsRepository.mainPrefsFlow,
unitsRepo.allUnits
) { unitFrom, ui, prefs, _ ->
return@combine ui.copy(
unitFrom = unitFrom,
sorting = prefs.unitConverterSorting,
shownUnitGroups = prefs.shownUnitGroups,
favorites = prefs.unitConverterFavoritesOnly
)
}.stateIn(
viewModelScope, SharingStarted.WhileSubscribed(5000), ConverterUIState()
)
fun addTokens(tokens: String) = _input.update { it.addTokens(tokens) }
fun deleteTokens() = _input.update { it.deleteTokens() }
fun clearInput() = _input.update { TextFieldValue() }
fun onCursorChange(selection: TextRange) = _input.update { it.copy(selection = selection) }
/**
* Update [_unitFrom] and set [_unitTo] from pair. Also updates stats for this [unit].
*/
fun updateUnitFrom(unit: AbstractUnit) {
// We change from something to base converter or the other way around
if ((_unitFrom.value?.group == UnitGroup.NUMBER_BASE) xor (unit.group == UnitGroup.NUMBER_BASE)) {
_calculated.update { null }
clearInput()
}
_unitFrom.update { unit }
/**
* Update pair [_unitTo] if it exists
*/
val pair = unit.pairedUnit
if (pair != null) {
_unitTo.update { allUnitsRepository.getById(pair) }
} else {
// No pair, get something from same group
_unitTo.update { allUnitsRepository.getCollectionByGroup(unit.group).first() }
}
incrementCounter(unit)
saveLatestPairOfUnits()
updateCurrenciesRatesIfNeeded()
}
.onEach {
filterUnitsLeft(
query = it.query,
unitGroup = it.unitGroup,
favoritesOnly = it.favorites,
sorting = it.sorting,
shownUnitGroups = it.shownUnitGroups
)
}
.stateIn(viewModelScope, SharingStarted.Lazily, LeftSideUIState())
/**
* Update [_unitTo] and update pair for [_unitFrom].
*/
fun updateUnitTo(unit: AbstractUnit) {
_unitTo.update { unit }
_unitFrom.value?.pairedUnit = unit.unitId
updatePairedUnit(_unitFrom.value ?: return)
incrementCounter(unit)
saveLatestPairOfUnits()
val rightSideUIState = combine(
_unitFrom,
_unitTo,
_input,
_calculation,
_rightSideUIState,
userPrefsRepository.mainPrefsFlow,
unitsRepo.allUnits
) { unitFrom, unitTo, input, calculation, ui, prefs, _ ->
return@combine ui.copy(
unitFrom = unitFrom,
unitTo = unitTo,
sorting = prefs.unitConverterSorting,
favorites = prefs.unitConverterFavoritesOnly,
input = calculation?.toPlainString() ?: input.text,
scale = prefs.digitsPrecision,
outputFormat = prefs.outputFormat,
)
}
.onEach {
filterUnitsRight(
query = it.query,
unitGroup = it.unitTo?.group,
favoritesOnly = it.favorites,
sorting = it.sorting,
shownUnitGroups = emptyList(),
)
}
.stateIn(viewModelScope, SharingStarted.Lazily, RightSideUIState())
/**
* Swap [_unitFrom] and [_unitTo].
*/
fun swapUnits() {
_unitFrom
.getAndUpdate { _unitTo.value }
.also { oldUnitFrom -> _unitTo.update { oldUnitFrom } }
saveLatestPairOfUnits()
updateCurrenciesRatesIfNeeded()
}
private fun convertInput() {
when (_unitFrom.value?.group) {
UnitGroup.NUMBER_BASE -> convertAsNumberBase()
else -> convertAsExpression()
}
}
private fun convertAsNumberBase() = viewModelScope.launch(Dispatchers.Default) {
// Units are still loading, don't convert anything yet
val unitFrom = _unitFrom.value ?: return@launch
val unitTo = _unitTo.value ?: return@launch
val conversionResult = try {
(unitFrom as NumberBaseUnit).convertToBase(
input = _input.value.text.ifEmpty { "0" },
toBase = (unitTo as NumberBaseUnit).base
)
} catch (e: Exception) {
when (e) {
is ClassCastException -> return@launch
is NumberFormatException, is IllegalArgumentException -> ""
else -> throw e
}
}
_result.update { ConversionResult.NumberBase(conversionResult) }
}
private fun convertAsExpression() = viewModelScope.launch(Dispatchers.Default) {
val unitFrom = _unitFrom.value ?: return@launch
val unitTo = _unitTo.value ?: return@launch
val input = _input.value.text.ifEmpty { "0" }
if (input.isEmpty()) {
_calculated.update { null }
_result.update { ConversionResult.Default("") }
return@launch
_loadCurrenciesJob?.cancel()
_loadingCurrencies.update { CurrencyRateUpdateState.READY }
_unitFrom.value?.let {
if (it.group == UnitGroup.CURRENCY) updateCurrencyRates(it)
}
val evaluationResult = try {
Expression(input)
.calculate()
.also {
if (it > BigDecimal.valueOf(Double.MAX_VALUE)) throw ExpressionException.TooBig()
}
.setMinimumRequiredScale(_userPrefs.value.digitsPrecision)
.trimZeros()
} catch (e: ExpressionException.DivideByZero) {
_calculated.update { null }
return@launch
} catch (e: Exception) {
return@launch
}
_calculated.update {
if (input.isExpression()) evaluationResult.toStringWith(_userPrefs.value.outputFormat)
else null
}
val conversionResult = unitFrom.convert(
unitTo = unitTo,
value = evaluationResult,
scale = _userPrefs.value.digitsPrecision
).toStringWith(_userPrefs.value.outputFormat)
_result.update {
if ((unitFrom.group == UnitGroup.TIME) and (_userPrefs.value.unitConverterFormatTime))
ConversionResult.Time(conversionResult)
else
ConversionResult.Default(conversionResult)
}
}
private fun incrementCounter(unit: AbstractUnit) {
viewModelScope.launch(Dispatchers.IO) {
unitRepository.insertUnits(
UnitsEntity(
unitId = unit.unitId,
isFavorite = unit.isFavorite,
pairedUnitId = unit.pairedUnit,
// This will increment counter on unit in list too
frequency = ++unit.counter
)
)
}
}
private fun updatePairedUnit(unit: AbstractUnit) {
viewModelScope.launch(Dispatchers.IO) {
unitRepository.insertUnits(
UnitsEntity(
unitId = unit.unitId,
isFavorite = unit.isFavorite,
pairedUnitId = unit.pairedUnit,
frequency = unit.counter
)
)
}
}
fun updateCurrenciesRatesIfNeeded() {
viewModelScope.launch(Dispatchers.IO) {
_showError.update { false }
_showLoading.update { false }
// Units are still loading, don't convert anything yet
if (_unitFrom.value?.group != UnitGroup.CURRENCY) return@launch
val unitFrom = _unitFrom.value ?: return@launch
// Starting to load stuff
_showLoading.update { true }
try {
allUnitsRepository.updateBasicUnitsForCurrencies(unitFrom)
convertAsExpression()
} catch (e: Exception) {
// Dangerous and stupid, but who cares
_showError.update { true }
} finally {
/**
* Loaded, convert (this will trigger flow to call convertInput). Even if there was
* an error, it's OK and user will not see conversion result in that case.
*/
_showLoading.update { false }
}
}
}
private fun saveLatestPairOfUnits() {
viewModelScope.launch(Dispatchers.IO) {
// Units are still loading, don't convert anything yet
val unitFrom = _unitFrom.value ?: return@launch
val unitTo = _unitTo.value ?: return@launch
userPrefsRepository.updateLatestPairOfUnits(unitFrom, unitTo)
}
}
private fun startObserving() {
viewModelScope.launch {
merge(_input, _unitFrom, _unitTo, _showLoading, _userPrefs).collectLatest {
convertInput()
val unitTo = _unitTo.value ?: return@launch
val unitFrom = _unitFrom.value ?: return@launch
userPrefsRepository.updateLatestPairOfUnits(unitFrom = unitFrom, unitTo = unitTo)
}
}
fun addTokens(tokens: String) = _input.update { it.addTokens(tokens) }
fun deleteTokens() = _input.update { it.deleteTokens() }
fun clearInput() = _input.update { TextFieldValue() }
fun onCursorChange(selection: TextRange) = _input.update { it.copy(selection = selection) }
fun updateCurrencyRates(unit: AbstractUnit) {
_loadCurrenciesJob = viewModelScope.launch(Dispatchers.IO) {
try {
_loadingCurrencies.update { CurrencyRateUpdateState.LOADING }
unitsRepo.updateRates(unit)
// Set to fresh objects with updated basic unit values
_unitFrom.update { unitsRepo.getById(it!!.id) }
_unitTo.update { unitsRepo.getById(it!!.id) }
_loadingCurrencies.update { CurrencyRateUpdateState.READY }
} catch (e: Exception) {
_loadingCurrencies.update { CurrencyRateUpdateState.ERROR }
}
}
}
private fun loadInitialUnitPair() {
viewModelScope.launch(Dispatchers.IO) {
val initialUserPrefs = userPrefsRepository.mainPreferencesFlow.first()
fun updateUnitFrom(unit: AbstractUnit) {
val pair = unitsRepo.getById(
unit.pairId ?: unitsRepo.getCollection(unit.group).first().id
)
// First we load latest pair of units
_unitFrom.update {
try {
allUnitsRepository.getById(initialUserPrefs.latestLeftSideUnit)
} catch (e: java.util.NoSuchElementException) {
allUnitsRepository.getById(MyUnitIDS.kilometer)
}
}
viewModelScope.launch(Dispatchers.Default) {
unitsRepo.incrementCounter(unit)
userPrefsRepository.updateLatestPairOfUnits(unitFrom = unit, unitTo = pair)
}
_unitTo.update {
try {
allUnitsRepository.getById(initialUserPrefs.latestRightSideUnit)
} catch (e: java.util.NoSuchElementException) {
allUnitsRepository.getById(MyUnitIDS.mile)
}
}
_loadCurrenciesJob?.cancel()
_loadingCurrencies.update { CurrencyRateUpdateState.READY }
if (unit.group == UnitGroup.CURRENCY) updateCurrencyRates(unit)
updateCurrenciesRatesIfNeeded()
_unitFrom.update {
// We change from something to base converter or the other way around
if ((it?.group == UnitGroup.NUMBER_BASE) xor (unit.group == UnitGroup.NUMBER_BASE))
clearInput()
unit
}
_unitTo.update { pair }
}
fun updateUnitTo(unit: AbstractUnit) {
_unitTo.update { unit }
viewModelScope.launch {
val unitTo = _unitTo.value ?: return@launch
val unitFrom = _unitFrom.value ?: return@launch
unitsRepo.incrementCounter(unitTo)
unitsRepo.setPair(unitFrom, unitTo)
userPrefsRepository.updateLatestPairOfUnits(unitFrom = unitFrom, unitTo = unitTo)
}
}
fun queryChangeLeft(query: TextFieldValue) = _leftSideUIState.update {
it.copy(query = query)
}
fun queryChangeRight(query: TextFieldValue) = _rightSideUIState.update {
it.copy(query = query)
}
fun favoritesOnlyChange(enabled: Boolean) = viewModelScope.launch {
userPrefsRepository.updateUnitConverterFavoritesOnly(enabled)
}
fun updateUnitGroupLeft(unitGroup: UnitGroup?) = _leftSideUIState.update {
it.copy(unitGroup = unitGroup)
}
fun favoriteUnit(unit: AbstractUnit) = viewModelScope.launch {
unitsRepo.favorite(unit)
}
private fun filterUnitsLeft(
query: TextFieldValue,
unitGroup: UnitGroup?,
favoritesOnly: Boolean,
sorting: UnitsListSorting,
shownUnitGroups: List<UnitGroup>,
) = viewModelScope.launch(Dispatchers.Default) {
_leftSideUIState.update {
it.copy(
units = unitsRepo.filterUnits(
query = query.text,
unitGroup = unitGroup,
favoritesOnly = favoritesOnly,
hideBrokenUnits = false,
sorting = sorting,
shownUnitGroups = shownUnitGroups
)
)
}
}
private fun filterUnitsRight(
query: TextFieldValue,
unitGroup: UnitGroup?,
favoritesOnly: Boolean,
sorting: UnitsListSorting,
shownUnitGroups: List<UnitGroup>,
) = viewModelScope.launch(Dispatchers.Default) {
_rightSideUIState.update {
it.copy(
units = unitsRepo.filterUnits(
query = query.text,
unitGroup = unitGroup,
favoritesOnly = favoritesOnly,
hideBrokenUnits = true,
sorting = sorting,
shownUnitGroups = shownUnitGroups
)
)
}
}
private fun convertDefault(
unitFrom: DefaultUnit,
unitTo: DefaultUnit,
input: TextFieldValue,
formatTime: Boolean,
) = viewModelScope.launch(Dispatchers.Default) {
val calculated = try {
Expression(input.text.ifEmpty { Token.Digit._0 }).calculate()
} catch (e: Exception) {
null
}
_calculation.update { if (input.text.isExpression()) calculated else null }
if (calculated == null) return@launch
try {
if ((unitFrom.group == UnitGroup.TIME) and (formatTime)) {
_result.update { formatTime(calculated.multiply(unitFrom.basicUnit)) }
return@launch
}
val conversion = unitFrom.convert(unitTo, calculated)
_result.update { ConverterResult.Default(conversion) }
} catch (e: Exception) {
_result.update { ConverterResult.Default(BigDecimal.ZERO) }
}
}
private fun convertNumberBase(
unitFrom: NumberBaseUnit,
unitTo: NumberBaseUnit,
input: TextFieldValue,
) = viewModelScope.launch(Dispatchers.Default) {
val conversion = try {
unitFrom.convert(unitTo, input.text.ifEmpty { Token.Digit._0 })
} catch (e: Exception) {
""
}
_result.update { ConverterResult.NumberBase(conversion) }
}
init {
loadInitialUnitPair()
startObserving()
viewModelScope.launch(Dispatchers.Default) {
val userPrefs = userPrefsRepository.mainPrefsFlow.first()
val unitFrom = unitsRepo.getById(userPrefs.latestLeftSideUnit)
val unitTo = unitsRepo.getById(userPrefs.latestRightSideUnit)
_unitFrom.update { unitFrom }
_unitTo.update { unitTo }
if (unitFrom.group == UnitGroup.CURRENCY) updateCurrencyRates(unitFrom)
}
}
}

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.unitslist
package com.sadellie.unitto.feature.converter
import androidx.compose.animation.Crossfade
import androidx.compose.animation.animateColorAsState
@ -41,52 +41,76 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
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.AbstractUnit
import com.sadellie.unitto.feature.unitslist.components.ChipsRow
import com.sadellie.unitto.feature.unitslist.components.FavoritesButton
import com.sadellie.unitto.feature.unitslist.components.SearchPlaceholder
import com.sadellie.unitto.feature.unitslist.components.UnitGroupHeader
import com.sadellie.unitto.feature.unitslist.components.UnitListItem
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.feature.converter.components.BasicUnitListItem
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
/**
* Left side screen. Unit to convert from.
*
* @param viewModel [UnitsListViewModel].
* @param currentUnitId Currently selected [AbstractUnit] (by ID).
* @param navigateUp Action to navigate up. Called when user click back button.
* @param navigateToSettingsAction Action to perform when clicking settings chip at the end.
* @param selectAction Action to perform when user clicks on [UnitListItem].
*/
@Composable
internal fun LeftSideScreen(
viewModel: UnitsListViewModel,
currentUnitId: String?,
internal fun LeftSideRoute(
viewModel: ConverterViewModel,
navigateUp: () -> Unit,
navigateToSettingsAction: () -> Unit,
selectAction: (AbstractUnit) -> Unit
navigateToUnitGroups: () -> Unit
) {
val uiState = viewModel.mainFlow.collectAsStateWithLifecycle()
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val chipsRowLazyListState = rememberLazyListState()
val focusManager = LocalFocusManager.current
val uiState = viewModel.leftSideUIState.collectAsStateWithLifecycle()
LeftSideScreen(
uiState = uiState.value,
onQueryChange = viewModel::queryChangeLeft,
toggleFavoritesOnly = viewModel::favoritesOnlyChange,
updateUnitFrom = viewModel::updateUnitFrom,
updateUnitGroup = viewModel::updateUnitGroupLeft,
favoriteUnit = viewModel::favoriteUnit,
navigateUp = navigateUp,
navigateToUnitGroups = navigateToUnitGroups,
)
}
@Composable
private fun LeftSideScreen(
uiState: LeftSideUIState,
onQueryChange: (TextFieldValue) -> Unit,
toggleFavoritesOnly: (Boolean) -> Unit,
updateUnitFrom: (AbstractUnit) -> Unit,
updateUnitGroup: (UnitGroup?) -> Unit,
favoriteUnit: (AbstractUnit) -> Unit,
navigateUp: () -> Unit,
navigateToUnitGroups: () -> Unit,
) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val elevatedColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp)
val needToTint by remember {
derivedStateOf { scrollBehavior.state.overlappedFraction > 0.01f }
}
val chipsBackground = animateColorAsState(
targetValue = if (needToTint) elevatedColor else MaterialTheme.colorScheme.surface,
animationSpec = tween(durationMillis = 500, easing = LinearOutSlowInEasing),
label = "Chips background",
)
val chipsRowLazyListState = rememberLazyListState()
LaunchedEffect(uiState.unitFrom, uiState.shownUnitGroups) {
// TODO Scroll to initially selected unit group
if (uiState.unitFrom == null) return@LaunchedEffect
updateUnitGroup(uiState.unitFrom.group)
val groupToSelect = uiState.shownUnitGroups.indexOf(uiState.unitFrom.group)
if (groupToSelect > -1) {
chipsRowLazyListState.animateScrollToItem(groupToSelect)
}
}
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
@ -94,67 +118,69 @@ internal fun LeftSideScreen(
Modifier.background(chipsBackground.value)
) {
UnittoSearchBar(
query = uiState.value.searchQuery,
onQueryChange = { viewModel.onSearchQueryChange(it, false) },
query = uiState.query,
onQueryChange = onQueryChange,
navigateUp = navigateUp,
title = stringResource(R.string.units_screen_from),
placeholder = stringResource(R.string.search_bar_placeholder),
noSearchActions = {
FavoritesButton(uiState.value.favoritesOnly) {
viewModel.toggleFavoritesOnly(false)
FavoritesButton(uiState.favorites) {
toggleFavoritesOnly(!uiState.favorites)
}
}
)
ChipsRow(
chosenUnitGroup = uiState.value.chosenUnitGroup,
items = uiState.value.shownUnitGroups,
selectAction = { viewModel.toggleSelectedChip(it, false) },
chosenUnitGroup = uiState.unitGroup,
items = uiState.shownUnitGroups,
selectAction = updateUnitGroup,
lazyListState = chipsRowLazyListState,
navigateToSettingsAction = navigateToSettingsAction
navigateToSettingsAction = navigateToUnitGroups
)
}
}
) { paddingValues ->
Crossfade(
targetState = uiState.value.unitsToShow.isEmpty(),
targetState = uiState.units?.isNotEmpty(),
modifier = Modifier.padding(paddingValues)
) { noUnits ->
if (noUnits) {
SearchPlaceholder(navigateToSettingsAction = navigateToSettingsAction)
} else {
LazyColumn(Modifier.fillMaxSize()) {
uiState.value.unitsToShow.forEach { (unitGroup, listOfUnits) ->
) { hasUnits ->
when (hasUnits) {
true -> LazyColumn(Modifier.fillMaxSize()) {
uiState.units?.forEach { (unitGroup, units) ->
item(unitGroup.name) {
UnitGroupHeader(Modifier.animateItemPlacement(), unitGroup)
}
items(listOfUnits, { it.unitId }) { unit ->
UnitListItem(
items(units, { it.id }) {
BasicUnitListItem(
modifier = Modifier.animateItemPlacement(),
unit = unit,
isSelected = currentUnitId == unit.unitId,
selectAction = {
selectAction(it)
viewModel.onSearchQueryChange("", false)
focusManager.clearFocus(true)
navigateUp()
},
favoriteAction = { viewModel.favoriteUnit(it) },
name = stringResource(it.displayName),
supportLabel = stringResource(it.shortName),
isFavorite = it.isFavorite,
isSelected = it.id == uiState.unitFrom?.id,
onClick = { updateUnitFrom(it); navigateUp() },
favoriteUnit = { favoriteUnit(it) }
)
}
}
}
false -> SearchPlaceholder(navigateToSettingsAction = navigateToUnitGroups)
null -> {}
}
}
}
LaunchedEffect(uiState.value.shownUnitGroups, currentUnitId) {
if (currentUnitId == null) return@LaunchedEffect
// This is still wrong, but works good enough.
// Ideally we shouldn't use uiState.value.shownUnitGroups
viewModel.setSelectedChip(currentUnitId, false)
val groupToSelect = uiState.value.shownUnitGroups.indexOf(uiState.value.chosenUnitGroup)
if (groupToSelect > -1) {
chipsRowLazyListState.animateScrollToItem(groupToSelect)
}
}
}
@Preview
@Composable
private fun LeftSideScreenPreview() {
LeftSideScreen(
uiState = LeftSideUIState(),
onQueryChange = {},
toggleFavoritesOnly = {},
updateUnitFrom = {},
updateUnitGroup = {},
favoriteUnit = {},
navigateUp = {},
navigateToUnitGroups = {}
)
}

View File

@ -0,0 +1,34 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.converter
import androidx.compose.ui.text.input.TextFieldValue
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,
)

View File

@ -0,0 +1,182 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.converter
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
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.R
import com.sadellie.unitto.core.ui.common.UnittoSearchBar
import com.sadellie.unitto.data.common.format
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.DefaultUnit
import com.sadellie.unitto.data.model.unit.NumberBaseUnit
import com.sadellie.unitto.feature.converter.components.BasicUnitListItem
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 RightSideRoute(
viewModel: ConverterViewModel,
navigateUp: () -> Unit,
navigateToUnitGroups: () -> Unit,
) {
val uiState = viewModel.rightSideUIState.collectAsStateWithLifecycle()
RightSideScreen(
uiState = uiState.value,
onQueryChange = viewModel::queryChangeRight,
toggleFavoritesOnly = viewModel::favoritesOnlyChange,
updateUnitTo = viewModel::updateUnitTo,
favoriteUnit = viewModel::favoriteUnit,
navigateUp = navigateUp,
navigateToUnitGroups = navigateToUnitGroups,
)
}
@Composable
private fun RightSideScreen(
uiState: RightSideUIState,
onQueryChange: (TextFieldValue) -> Unit,
toggleFavoritesOnly: (Boolean) -> Unit,
updateUnitTo: (AbstractUnit) -> Unit,
favoriteUnit: (AbstractUnit) -> Unit,
navigateUp: () -> Unit,
navigateToUnitGroups: () -> Unit,
) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
UnittoSearchBar(
query = uiState.query,
onQueryChange = onQueryChange,
navigateUp = navigateUp,
title = stringResource(R.string.units_screen_to),
placeholder = stringResource(R.string.search_bar_placeholder),
noSearchActions = {
FavoritesButton(uiState.favorites) {
toggleFavoritesOnly(!uiState.favorites)
}
},
scrollBehavior = scrollBehavior
)
}
) { paddingValues ->
Crossfade(
targetState = uiState.units?.isNotEmpty(),
modifier = Modifier.padding(paddingValues)
) { hasUnits ->
when (hasUnits) {
true -> LazyColumn(Modifier.fillMaxSize()) {
uiState.units?.forEach { (unitGroup, units) ->
item(unitGroup.name) {
UnitGroupHeader(Modifier.animateItemPlacement(), unitGroup)
}
items(units, { it.id }) {
BasicUnitListItem(
modifier = Modifier.animateItemPlacement(),
name = stringResource(it.displayName),
supportLabel = formatUnitToSupportLabel(
unitFrom = uiState.unitFrom,
unitTo = it,
input = uiState.input,
shortName = stringResource(it.shortName),
scale = uiState.scale,
outputFormat = uiState.outputFormat
),
isFavorite = it.isFavorite,
isSelected = it.id == uiState.unitTo?.id,
onClick = { updateUnitTo(it); navigateUp() },
favoriteUnit = { favoriteUnit(it) }
)
}
}
}
false -> SearchPlaceholder(navigateToSettingsAction = navigateToUnitGroups)
null -> {}
}
}
}
}
private fun formatUnitToSupportLabel(
unitFrom: AbstractUnit?,
unitTo: AbstractUnit?,
input: String,
shortName: String,
scale: Int,
outputFormat: Int
): String {
try {
if ((unitFrom is DefaultUnit) and (unitTo is DefaultUnit)) {
unitFrom as DefaultUnit
unitTo as DefaultUnit
val conversion = unitFrom.convert(unitTo, BigDecimal(input)).format(scale, outputFormat)
return "$conversion $shortName"
}
if ((unitFrom is NumberBaseUnit) and (unitTo is NumberBaseUnit)) {
unitFrom as NumberBaseUnit
unitTo as NumberBaseUnit
val conversion = unitFrom.convert(unitTo, input).uppercase()
return "$conversion $shortName"
}
} catch (e: Exception) {
return shortName
}
return shortName
}
@Preview
@Composable
private fun RightSideScreenPreview() {
RightSideScreen(
uiState = RightSideUIState(),
onQueryChange = {},
toggleFavoritesOnly = {},
updateUnitTo = {},
favoriteUnit = {},
navigateUp = {},
navigateToUnitGroups = {}
)
}

View File

@ -0,0 +1,38 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.converter
import androidx.compose.ui.text.input.TextFieldValue
import com.sadellie.unitto.core.base.OutputFormat
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,
)

View File

@ -1,6 +1,6 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2023 Elshan Agaev
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,9 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.unitslist.components
package com.sadellie.unitto.feature.converter.components
import android.annotation.SuppressLint
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.SizeTransform
import androidx.compose.animation.scaleIn
@ -43,11 +42,7 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@ -55,44 +50,34 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.data.model.AbstractUnit
/**
* Represents one list item. Once clicked will navigate up.
*
* @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.
*/
@SuppressLint("UnusedContentLambdaTargetStateParameter")
@Composable
private fun BasicUnitListItem(
internal fun BasicUnitListItem(
modifier: Modifier,
unit: AbstractUnit,
name: String,
supportLabel: String,
isFavorite: Boolean,
isSelected: Boolean,
selectAction: (AbstractUnit) -> Unit,
favoriteAction: (AbstractUnit) -> Unit,
shortNameLabel: String
onClick: () -> Unit,
favoriteUnit: () -> Unit,
) {
var isFavorite: Boolean by rememberSaveable { mutableStateOf(unit.isFavorite) }
Box(
modifier = modifier
.background(MaterialTheme.colorScheme.surface)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(),
onClick = { selectAction(unit) }
onClick = onClick
)
.padding(horizontal = 12.dp)
) {
Row(
modifier = Modifier
.background(
if (isSelected) MaterialTheme.colorScheme.primaryContainer else Color.Transparent,
RoundedCornerShape(24.dp)
).padding(paddingValues = PaddingValues(horizontal = 12.dp, vertical = 8.dp))
.background(
if (isSelected) MaterialTheme.colorScheme.primaryContainer else Color.Transparent,
RoundedCornerShape(24.dp)
)
.padding(paddingValues = PaddingValues(horizontal = 12.dp, vertical = 8.dp))
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp)
@ -103,14 +88,14 @@ private fun BasicUnitListItem(
Text(
modifier = Modifier
.fillMaxWidth(),
text = stringResource(unit.displayName),
text = name,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
Text(
modifier = Modifier
.fillMaxWidth(),
text = shortNameLabel,
text = supportLabel,
style = MaterialTheme.typography.bodySmall,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
@ -122,7 +107,7 @@ private fun BasicUnitListItem(
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(false),
onClick = { favoriteAction(unit); isFavorite = !isFavorite }
onClick = favoriteUnit
),
targetState = isFavorite,
transitionSpec = {
@ -130,60 +115,10 @@ private fun BasicUnitListItem(
}
) {
Icon(
if (unit.isFavorite) Icons.Filled.Favorite else Icons.Filled.FavoriteBorder,
if (it) Icons.Filled.Favorite else Icons.Filled.FavoriteBorder,
contentDescription = stringResource(R.string.favorite_button_description)
)
}
}
}
}
/**
* 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
internal fun UnitListItem(
modifier: Modifier,
unit: AbstractUnit,
isSelected: Boolean,
selectAction: (AbstractUnit) -> Unit,
favoriteAction: (AbstractUnit) -> Unit,
) = BasicUnitListItem(
modifier = modifier,
unit = unit,
isSelected = isSelected,
selectAction = selectAction,
favoriteAction = favoriteAction,
shortNameLabel = stringResource(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
internal fun UnitListItem(
modifier: Modifier,
unit: AbstractUnit,
isSelected: Boolean,
selectAction: (AbstractUnit) -> Unit,
favoriteAction: (AbstractUnit) -> Unit,
convertValue: (AbstractUnit) -> String
) = BasicUnitListItem(
modifier = modifier,
unit = unit,
isSelected = isSelected,
selectAction = selectAction,
favoriteAction = favoriteAction,
shortNameLabel = "${convertValue(unit)}${stringResource(unit.shortName)}"
)

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.unitslist.components
package com.sadellie.unitto.feature.converter.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background
@ -63,7 +63,7 @@ import com.sadellie.unitto.data.model.UnitGroup
internal fun ChipsRow(
items: List<UnitGroup> = ALL_UNIT_GROUPS,
chosenUnitGroup: UnitGroup?,
selectAction: (UnitGroup) -> Unit,
selectAction: (UnitGroup?) -> Unit,
navigateToSettingsAction: () -> Unit,
lazyListState: LazyListState
) {
@ -79,7 +79,7 @@ internal fun ChipsRow(
val isSelected: Boolean = item == chosenUnitGroup
UnittoFilterChip(
isSelected = isSelected,
selectAction = { selectAction(item) }
selectAction = { selectAction(if (item == chosenUnitGroup) null else item) }
) {
AnimatedVisibility(visible = isSelected) {
Icon(

View File

@ -18,14 +18,19 @@
package com.sadellie.unitto.feature.converter.components
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import com.sadellie.unitto.core.base.Token
import com.sadellie.unitto.core.ui.common.ColumnWithConstraints
import com.sadellie.unitto.core.ui.common.KeyboardButtonFilled
@ -58,38 +63,10 @@ import com.sadellie.unitto.core.ui.common.key.unittoicons.Multiply
import com.sadellie.unitto.core.ui.common.key.unittoicons.Plus
import com.sadellie.unitto.core.ui.common.key.unittoicons.RightBracket
import com.sadellie.unitto.core.ui.common.key.unittoicons.SquareRoot
import com.sadellie.unitto.feature.converter.ConverterMode
/**
* Keyboard with button that looks like a calculator
*
* @param modifier Modifier that is applied to [Row]
* @param addDigit Function that is called when clicking number and dot buttons
* @param deleteDigit Function that is called when clicking delete "<" button
* @param clearInput Function that is called when clicking clear "AC" button
* @param converterMode
*/
@Composable
internal fun ConverterKeyboard(
modifier: Modifier = Modifier,
addDigit: (String) -> Unit = {},
deleteDigit: () -> Unit = {},
clearInput: () -> Unit = {},
converterMode: ConverterMode,
allowVibration: Boolean,
fractional: String,
middleZero: Boolean,
) {
Crossfade(converterMode, modifier = modifier) {
when (it) {
ConverterMode.DEFAULT -> DefaultKeyboard(addDigit, clearInput, deleteDigit, allowVibration, fractional, middleZero)
ConverterMode.BASE -> BaseKeyboard(addDigit, clearInput, deleteDigit, allowVibration)
}
}
}
@Composable
private fun DefaultKeyboard(
internal fun DefaultKeyboard(
modifier: Modifier,
addDigit: (String) -> Unit,
clearInput: () -> Unit,
deleteDigit: () -> Unit,
@ -98,7 +75,7 @@ private fun DefaultKeyboard(
middleZero: Boolean,
) {
val fractionalIcon = remember { if (fractional == Token.Digit.dot) UnittoIcons.Dot else UnittoIcons.Comma }
ColumnWithConstraints {
ColumnWithConstraints(modifier) {
// Button modifier
val bModifier = Modifier
.fillMaxSize()
@ -145,13 +122,14 @@ private fun DefaultKeyboard(
}
@Composable
private fun BaseKeyboard(
internal fun NumberBaseKeyboard(
modifier: Modifier,
addDigit: (String) -> Unit,
clearInput: () -> Unit,
deleteDigit: () -> Unit,
allowVibration: Boolean
) {
ColumnWithConstraints {
ColumnWithConstraints(modifier) {
// Button modifier
val bModifier = Modifier
.fillMaxSize()
@ -191,3 +169,15 @@ private fun BaseKeyboard(
}
}
}
@Composable
internal fun LoadingKeyboard(
modifier: Modifier,
) {
Box(
modifier = modifier
.clip(RoundedCornerShape(32.dp))
.background(MaterialTheme.colorScheme.inverseOnSurface)
.fillMaxSize()
)
}

View File

@ -1,6 +1,6 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2023 Elshan Agaev
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.unitslist.components
package com.sadellie.unitto.feature.converter.components
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.SizeTransform

View File

@ -1,6 +1,6 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2023 Elshan Agaev
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.unitslist.components
package com.sadellie.unitto.feature.converter.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@ -37,11 +37,6 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.sadellie.unitto.core.base.R
/**
* Placeholder that can be seen when there are no units found
*
* @param navigateToSettingsAction Action to perform when clicking open settings button.
*/
@Composable
internal fun SearchPlaceholder(navigateToSettingsAction: () -> Unit) {
Column(

View File

@ -1,322 +0,0 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.converter.components
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.Crossfade
import androidx.compose.animation.SizeTransform
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandHorizontally
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.SwapHoriz
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.core.base.Token
import com.sadellie.unitto.core.ui.common.ColumnWithConstraints
import com.sadellie.unitto.core.ui.common.textfield.ExpressionTextField
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
import com.sadellie.unitto.core.ui.common.textfield.UnformattedTextField
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
import com.sadellie.unitto.core.ui.common.textfield.formatTime
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.feature.converter.ConversionResult
import com.sadellie.unitto.feature.converter.ConverterMode
/**
* Top of the main screen. Contains input and output TextFields, and unit selection row of buttons.
* It's a separate composable, so that we support album orientation (this element will be on the left)
*
* @param modifier Modifier that is applied to Column.
* @param inputValue Current input value (like big decimal).
* @param calculatedValue Current calculated value (like big decimal), will be shown under input when it
* has an expression in it.
* @param outputValue Current output value (like big decimal).
* @param unitFrom [AbstractUnit] on the left.
* @param unitTo [AbstractUnit] on the right.
* @param navigateToLeftScreen Function that is called when clicking left unit selection button.
* @param navigateToRightScreen Function that is called when clicking right unit selection button.
* @param swapUnits Method to swap units.
* @param converterMode [ConverterMode.BASE] doesn't use formatting for input/output.
*/
@Composable
internal fun TopScreenPart(
modifier: Modifier,
inputValue: TextFieldValue,
calculatedValue: String?,
outputValue: ConversionResult,
unitFrom: AbstractUnit?,
unitTo: AbstractUnit?,
navigateToLeftScreen: (String) -> Unit,
navigateToRightScreen: (unitFrom: String, unitTo: String, input: String?) -> Unit,
swapUnits: () -> Unit,
converterMode: ConverterMode,
onCursorChange: (TextRange) -> Unit,
cutCallback: () -> Unit,
pasteCallback: (String) -> Unit,
formatterSymbols: FormatterSymbols,
onErrorClick: () -> Unit,
) {
var swapped by remember { mutableStateOf(false) }
val swapButtonRotation: Float by animateFloatAsState(
targetValue = if (swapped) 0f else 180f,
animationSpec = tween(easing = FastOutSlowInEasing),
label = "Swap button rotation"
)
val mContext = LocalContext.current
ColumnWithConstraints(
modifier = modifier,
) {
Crossfade(modifier = Modifier.weight(2f), targetState = converterMode) { mode ->
if (mode == ConverterMode.BASE) {
UnformattedTextField(
modifier = Modifier,
value = inputValue,
onCursorChange = onCursorChange,
minRatio = 0.7f,
cutCallback = cutCallback,
pasteCallback = pasteCallback,
placeholder = Token.Digit._0
)
} else {
ExpressionTextField(
modifier = Modifier,
value = inputValue,
onCursorChange = onCursorChange,
formatterSymbols = formatterSymbols,
minRatio = 0.7f,
cutCallback = cutCallback,
pasteCallback = pasteCallback,
placeholder = Token.Digit._0
)
}
}
AnimatedVisibility(
visible = !calculatedValue.isNullOrEmpty(),
modifier = Modifier.weight(1f),
enter = expandVertically(clip = false),
exit = shrinkVertically(clip = false)
) {
var calculatedTextFieldValue by remember(calculatedValue) {
mutableStateOf(
TextFieldValue(calculatedValue?.formatExpression(formatterSymbols) ?: "")
)
}
ExpressionTextField(
modifier = Modifier,
value = calculatedTextFieldValue,
onCursorChange = { newSelection ->
calculatedTextFieldValue =
calculatedTextFieldValue.copy(selection = newSelection)
},
formatterSymbols = formatterSymbols,
textColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f),
minRatio = 0.7f
)
}
AnimatedContent(
modifier = Modifier.fillMaxWidth(),
targetState = stringResource(unitFrom?.shortName ?: R.string.loading_label),
transitionSpec = {
// Enter animation
(expandHorizontally(clip = false, expandFrom = Alignment.Start) + fadeIn()
togetherWith fadeOut())
.using(SizeTransform(clip = false))
},
label = "Animated short name from"
) { value ->
Text(
text = value,
style = MaterialTheme.typography.bodyMedium.copy(textAlign = TextAlign.End)
)
}
when (outputValue) {
is ConversionResult.Default -> {
var outputTextFieldValue: TextFieldValue by remember(outputValue) {
mutableStateOf(TextFieldValue(outputValue.result))
}
ExpressionTextField(
modifier = Modifier.weight(2f),
value = outputTextFieldValue,
onCursorChange = { newSelection ->
outputTextFieldValue = outputTextFieldValue.copy(selection = newSelection)
},
formatterSymbols = formatterSymbols,
readOnly = true,
minRatio = 0.7f
)
}
is ConversionResult.Time -> {
var outputTextFieldValue: TextFieldValue by remember(outputValue) {
mutableStateOf(
TextFieldValue(
outputValue.result
.formatTime(mContext, unitTo?.basicUnit, formatterSymbols)
)
)
}
UnformattedTextField(
modifier = Modifier.weight(2f),
value = outputTextFieldValue,
onCursorChange = { newSelection ->
outputTextFieldValue = outputTextFieldValue.copy(selection = newSelection)
},
minRatio = 0.7f,
readOnly = true
)
}
is ConversionResult.NumberBase -> {
var outputTextFieldValue: TextFieldValue by remember(outputValue) {
mutableStateOf(TextFieldValue(outputValue.result.uppercase()))
}
UnformattedTextField(
modifier = Modifier.weight(2f),
value = outputTextFieldValue,
onCursorChange = { newSelection ->
outputTextFieldValue = outputTextFieldValue.copy(selection = newSelection)
},
minRatio = 0.7f,
readOnly = true
)
}
is ConversionResult.Loading -> {
UnformattedTextField(
modifier = Modifier.weight(2f),
value = TextFieldValue(stringResource(R.string.loading_label)),
onCursorChange = {},
minRatio = 0.7f,
readOnly = true
)
}
is ConversionResult.Error -> {
UnformattedTextField(
modifier = Modifier.weight(2f),
value = TextFieldValue(stringResource(R.string.error_label)),
onCursorChange = { onErrorClick() },
minRatio = 0.7f,
readOnly = true,
textColor = MaterialTheme.colorScheme.error
)
}
}
val supportLabelTo = when {
outputValue is ConversionResult.Error -> R.string.try_again_label
(unitTo?.shortName != null) -> unitTo.shortName
else -> R.string.loading_label
}
AnimatedContent(
modifier = Modifier.fillMaxWidth(),
targetState = stringResource(supportLabelTo),
transitionSpec = {
// Enter animation
(expandHorizontally(clip = false, expandFrom = Alignment.Start) + fadeIn()
// Exit animation
togetherWith fadeOut())
.using(SizeTransform(clip = false))
},
label = "Animated short label to"
) { value ->
Text(
text = value,
style = MaterialTheme.typography.bodyMedium.copy(textAlign = TextAlign.End)
)
}
Spacer(modifier = Modifier.height(it.maxHeight * 0.03f))
Row(verticalAlignment = Alignment.CenterVertically) {
UnitSelectionButton(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
onClick = { unitFrom?.let { unit -> navigateToLeftScreen(unit.unitId) } },
label = unitFrom?.displayName ?: R.string.loading_label,
)
IconButton(
onClick = {
swapUnits()
swapped = !swapped
},
enabled = unitFrom != null
) {
Icon(
modifier = Modifier.rotate(swapButtonRotation),
imageVector = Icons.Outlined.SwapHoriz,
contentDescription = stringResource(R.string.swap_units_description)
)
}
UnitSelectionButton(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
onClick = {
if (unitTo == null) return@UnitSelectionButton
if (unitFrom == null) return@UnitSelectionButton
val input = when (outputValue) {
is ConversionResult.Error, ConversionResult.Loading -> null
else -> calculatedValue ?: inputValue.text
}
navigateToRightScreen(
unitFrom.unitId,
unitTo.unitId,
input?.ifEmpty { "0" }
)
},
label = unitTo?.displayName ?: R.string.loading_label,
)
}
}
}

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.unitslist.components
package com.sadellie.unitto.feature.converter.components
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.runtime.Composable

View File

@ -32,10 +32,8 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.core.ui.common.UnittoButton
/**
@ -50,17 +48,18 @@ import com.sadellie.unitto.core.ui.common.UnittoButton
internal fun UnitSelectionButton(
modifier: Modifier = Modifier,
onClick: () -> Unit = {},
label: Int?,
label: String,
enabled: Boolean = true
) {
UnittoButton(
modifier = modifier,
onClick = onClick,
enabled = label != null,
enabled = enabled,
containerColor = MaterialTheme.colorScheme.primaryContainer,
contentPadding = PaddingValues(vertical = 16.dp, horizontal = 8.dp),
) {
AnimatedContent(
targetState = label ?: 0,
targetState = label,
transitionSpec = {
if (targetState > initialState) {
(slideInVertically { height -> height } + fadeIn()) togetherWith
@ -74,7 +73,7 @@ internal fun UnitSelectionButton(
}
) {
Text(
text = stringResource(label ?: R.string.loading_label),
text = it,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = MaterialTheme.colorScheme.onSecondaryContainer

View File

@ -18,23 +18,29 @@
package com.sadellie.unitto.feature.converter.navigation
import androidx.compose.runtime.remember
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.composable
import androidx.navigation.compose.navigation
import androidx.navigation.navDeepLink
import com.sadellie.unitto.core.base.TopLevelDestinations
import com.sadellie.unitto.feature.converter.ConverterRoute
import com.sadellie.unitto.feature.converter.ConverterViewModel
import com.sadellie.unitto.feature.converter.LeftSideRoute
import com.sadellie.unitto.feature.converter.RightSideRoute
private val graph = TopLevelDestinations.Converter.graph
private val start = TopLevelDestinations.Converter.start
private const val LEFT = "left"
private const val RIGHT = "right"
fun NavGraphBuilder.converterGraph(
navigateToLeftScreen: (String) -> Unit,
navigateToRightScreen: (unitFrom: String, unitTo: String, input: String?) -> Unit,
openDrawer: () -> Unit,
navController: NavHostController,
navigateToSettings: () -> Unit,
navigateToMenu: () -> Unit,
viewModel: ConverterViewModel
navigateToUnitGroups: () -> Unit,
) {
navigation(
startDestination = start,
@ -43,13 +49,47 @@ fun NavGraphBuilder.converterGraph(
navDeepLink { uriPattern = "app://com.sadellie.unitto/$graph" }
)
) {
composable(start) {
composable(start) { backStackEntry ->
val parentEntry = remember(backStackEntry) {
navController.getBackStackEntry(graph)
}
val parentViewModel = hiltViewModel<ConverterViewModel>(parentEntry)
ConverterRoute(
viewModel = viewModel,
navigateToLeftScreen = navigateToLeftScreen,
navigateToRightScreen = navigateToRightScreen,
viewModel = parentViewModel,
navigateToLeftScreen = { navController.navigate(LEFT) },
navigateToRightScreen = { navController.navigate(RIGHT) },
navigateToSettings = navigateToSettings,
navigateToMenu = navigateToMenu
navigateToMenu = openDrawer
)
}
composable(LEFT) { backStackEntry ->
val parentEntry = remember(backStackEntry) {
navController.getBackStackEntry(graph)
}
val parentViewModel = hiltViewModel<ConverterViewModel>(parentEntry)
LeftSideRoute(
viewModel = parentViewModel,
navigateUp = navController::navigateUp,
navigateToUnitGroups = navigateToUnitGroups
)
}
composable(RIGHT) { backStackEntry ->
val parentEntry = remember(backStackEntry) {
navController.getBackStackEntry(graph)
}
val parentViewModel = hiltViewModel<ConverterViewModel>(parentEntry)
RightSideRoute(
viewModel = parentViewModel,
navigateUp = navController::navigateUp,
navigateToUnitGroups = navigateToUnitGroups
)
}
}

View File

@ -0,0 +1,133 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.converter
import android.content.Context
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import java.math.BigDecimal
@RunWith(RobolectricTestRunner::class)
class ConverterUIStateKtTest {
@Test
fun format() {
val formatterSymbols = FormatterSymbols.Spaces
var basicValue = BigDecimal.valueOf(1)
val mContext: Context = RuntimeEnvironment.getApplication().applicationContext
fun String.formatTime() = formatTime(basicValue.multiply(BigDecimal(this)))
.format(mContext, formatterSymbols)
// Edgy things (minus, decimals and zeros)
Assert.assertEquals("28as", "-28".formatTime())
Assert.assertEquals("0.05as", "-0.05".formatTime())
Assert.assertEquals("0", "0".formatTime())
basicValue = BigDecimal.valueOf(86_400_000_000_000_000_000_000.0)
Assert.assertEquals("28d", "-28".formatTime())
Assert.assertEquals("1h 12m", "-0.05".formatTime())
Assert.assertEquals("0", "0".formatTime())
Assert.assertEquals("0", "-0".formatTime())
// DAYS
basicValue = BigDecimal.valueOf(86_400_000_000_000_000_000_000.0)
Assert.assertEquals("12h", "0.5".formatTime())
Assert.assertEquals("1h 12m", "0.05".formatTime())
Assert.assertEquals("7m 12s", "0.005".formatTime())
Assert.assertEquals("28d", "28".formatTime())
Assert.assertEquals("90d", "90".formatTime())
Assert.assertEquals("90d 12h", "90.5".formatTime())
Assert.assertEquals("90d 7m 12s", "90.005".formatTime())
// HOURS
basicValue = BigDecimal.valueOf(3_600_000_000_000_000_000_000.0)
Assert.assertEquals("30m", "0.5".formatTime())
Assert.assertEquals("3m", "0.05".formatTime())
Assert.assertEquals("18s", "0.005".formatTime())
Assert.assertEquals("1d 4h", "28".formatTime())
Assert.assertEquals("3d 18h", "90".formatTime())
Assert.assertEquals("3d 18h 30m", "90.5".formatTime())
Assert.assertEquals("3d 18h 18s", "90.005".formatTime())
// MINUTES
basicValue = BigDecimal.valueOf(60_000_000_000_000_000_000.0)
Assert.assertEquals("30s", "0.5".formatTime())
Assert.assertEquals("3s", "0.05".formatTime())
Assert.assertEquals("300ms", "0.005".formatTime())
Assert.assertEquals("28m", "28".formatTime())
Assert.assertEquals("1h 30m", "90".formatTime())
Assert.assertEquals("1h 30m 30s", "90.5".formatTime())
Assert.assertEquals("1h 30m 300ms", "90.005".formatTime())
// SECONDS
basicValue = BigDecimal.valueOf(1_000_000_000_000_000_000)
Assert.assertEquals("500ms", "0.5".formatTime())
Assert.assertEquals("50ms", "0.05".formatTime())
Assert.assertEquals("5ms", "0.005".formatTime())
Assert.assertEquals("28s", "28".formatTime())
Assert.assertEquals("1m 30s", "90".formatTime())
Assert.assertEquals("1m 30s 500ms", "90.5".formatTime())
Assert.assertEquals("1m 30s 5ms", "90.005".formatTime())
// MILLISECONDS
basicValue = BigDecimal.valueOf(1_000_000_000_000_000)
Assert.assertEquals("500µs", "0.5".formatTime())
Assert.assertEquals("50µs", "0.05".formatTime())
Assert.assertEquals("5µs", "0.005".formatTime())
Assert.assertEquals("28ms", "28".formatTime())
Assert.assertEquals("90ms", "90".formatTime())
Assert.assertEquals("90ms 500µs", "90.5".formatTime())
Assert.assertEquals("90ms 5µs", "90.005".formatTime())
// MICROSECONDS
basicValue = BigDecimal.valueOf(1_000_000_000_000)
Assert.assertEquals("500ns", "0.5".formatTime())
Assert.assertEquals("50ns", "0.05".formatTime())
Assert.assertEquals("5ns", "0.005".formatTime())
Assert.assertEquals("28µs", "28".formatTime())
Assert.assertEquals("90µs", "90".formatTime())
Assert.assertEquals("90µs 500ns", "90.5".formatTime())
Assert.assertEquals("90µs 5ns", "90.005".formatTime())
// NANOSECONDS
basicValue = BigDecimal.valueOf(1_000_000_000)
Assert.assertEquals("500 000 000as", "0.5".formatTime())
Assert.assertEquals("50 000 000as", "0.05".formatTime())
Assert.assertEquals("5 000 000as", "0.005".formatTime())
Assert.assertEquals("28ns", "28".formatTime())
Assert.assertEquals("90ns", "90".formatTime())
Assert.assertEquals("90ns 500 000 000as", "90.5".formatTime())
Assert.assertEquals("90ns 5 000 000as", "90.005".formatTime())
// ATTOSECONDS
basicValue = BigDecimal.valueOf(1)
Assert.assertEquals("0.5as", "0.5".formatTime())
Assert.assertEquals("0.05as", "0.05".formatTime())
Assert.assertEquals("0.005as", "0.005".formatTime())
Assert.assertEquals("28as", "28".formatTime())
Assert.assertEquals("90as", "90".formatTime())
Assert.assertEquals("90.5as", "90.5".formatTime())
Assert.assertEquals("90.005as", "90.005".formatTime())
}
}

View File

@ -43,7 +43,7 @@ import kotlin.math.ceil
class FormattingViewModel @Inject constructor(
private val userPreferencesRepository: UserPreferencesRepository
) : ViewModel() {
private val _mainPreferences = userPreferencesRepository.mainPreferencesFlow
private val _mainPreferences = userPreferencesRepository.mainPrefsFlow
private val _fractional = MutableStateFlow(false)
val uiState = combine(_mainPreferences, _fractional) { mainPrefs, fractional ->

View File

@ -87,7 +87,7 @@ class UnitGroupsViewModel @Inject constructor(
init {
viewModelScope.launch {
unitGroupsRepository.updateShownGroups(
userPrefsRepository.mainPreferencesFlow.first().shownUnitGroups
userPrefsRepository.mainPrefsFlow.first().shownUnitGroups
)
}
}

View File

@ -40,6 +40,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
@ -83,7 +84,7 @@ internal fun AddTimeZoneRoute(
fun AddTimeZoneScreen(
uiState: AddTimeZoneUIState,
navigateUp: () -> Unit,
onQueryChange: (String) -> Unit,
onQueryChange: (TextFieldValue) -> Unit,
addToFavorites: (UnittoTimeZone) -> Unit,
) {
val listState = rememberLazyListState()

View File

@ -18,11 +18,12 @@
package com.sadellie.unitto.timezone
import androidx.compose.ui.text.input.TextFieldValue
import com.sadellie.unitto.data.model.UnittoTimeZone
import java.time.ZonedDateTime
data class AddTimeZoneUIState(
val query: String = "",
val query: TextFieldValue = TextFieldValue(),
val list: List<UnittoTimeZone> = emptyList(),
val userTime: ZonedDateTime? = null,
)

View File

@ -18,6 +18,7 @@
package com.sadellie.unitto.timezone
import androidx.compose.ui.text.input.TextFieldValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sadellie.unitto.data.model.UnittoTimeZone
@ -39,7 +40,7 @@ class AddTimeZoneViewModel @Inject constructor(
) : ViewModel() {
private val _userTime = MutableStateFlow<ZonedDateTime?>(ZonedDateTime.now())
private val _query = MutableStateFlow("")
private val _query = MutableStateFlow(TextFieldValue())
private val _filteredTimeZones = MutableStateFlow(emptyList<UnittoTimeZone>())
val addTimeZoneUIState = combine(
@ -56,9 +57,9 @@ class AddTimeZoneViewModel @Inject constructor(
viewModelScope, SharingStarted.WhileSubscribed(5000), AddTimeZoneUIState()
)
fun onQueryChange(query: String) {
fun onQueryChange(query: TextFieldValue) {
_query.update { query }
filterTimeZones(query)
filterTimeZones(query.text)
}
private fun filterTimeZones(query: String = "") = viewModelScope.launch {

View File

@ -1 +0,0 @@
/build

View File

@ -1,35 +0,0 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
plugins {
id("unitto.library")
id("unitto.library.compose")
id("unitto.library.feature")
id("unitto.android.hilt")
}
android {
namespace = "com.sadellie.unitto.feature.unitslist"
}
dependencies {
implementation(project(mapOf("path" to ":data:model")))
implementation(project(mapOf("path" to ":data:userprefs")))
implementation(project(mapOf("path" to ":data:units")))
implementation(project(mapOf("path" to ":data:database")))
}

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Unitto is a unit converter for Android
~ Copyright (c) 2023 Elshan Agaev
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<manifest>
</manifest>

View File

@ -1,169 +0,0 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.unitslist
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
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.model.AbstractUnit
import com.sadellie.unitto.data.model.NumberBaseUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.feature.unitslist.components.FavoritesButton
import com.sadellie.unitto.feature.unitslist.components.SearchPlaceholder
import com.sadellie.unitto.feature.unitslist.components.UnitGroupHeader
import com.sadellie.unitto.feature.unitslist.components.UnitListItem
import java.math.BigDecimal
/**
* Right side screen. Unit to convert to.
*
* @param viewModel [UnitsListViewModel].
* @param currentUnit Currently selected [AbstractUnit].
* @param navigateUp Action to navigate up. Called when user click back button.
* @param navigateToSettingsAction Action to perform when clicking settings chip at the end.
* @param selectAction Action to perform when user clicks on [UnitListItem].
* @param inputValue Current input value (upper text field on MainScreen)
* @param unitFrom Unit we are converting from. Need it for conversion.
*/
@Composable
internal fun RightSideScreen(
viewModel: UnitsListViewModel,
currentUnit: String,
navigateUp: () -> Unit,
navigateToSettingsAction: () -> Unit,
selectAction: (AbstractUnit) -> Unit,
inputValue: String?,
unitFrom: AbstractUnit
) {
val uiState = viewModel.mainFlow.collectAsStateWithLifecycle()
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val focusManager = LocalFocusManager.current
val convertMethod: (AbstractUnit) -> String = try {
val inputAsBigDecimal = BigDecimal(inputValue)
when {
inputValue.isNullOrEmpty() -> { { "" } }
unitFrom.group == UnitGroup.NUMBER_BASE -> {
{ (convertForSecondaryNumberBase(inputValue, unitFrom, it)) }
}
else -> {
{
convertForSecondary(inputAsBigDecimal, unitFrom, it, uiState.value.formatterSymbols)
}
}
}
} catch (e: Exception) {
{ "" }
}
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
UnittoSearchBar(
query = uiState.value.searchQuery,
onQueryChange = { viewModel.onSearchQueryChange(it, true) },
navigateUp = navigateUp,
title = stringResource(R.string.units_screen_to),
placeholder = stringResource(R.string.search_bar_placeholder),
noSearchActions = {
FavoritesButton(uiState.value.favoritesOnly) {
viewModel.toggleFavoritesOnly(true)
}
}
)
}
) { paddingValues ->
Crossfade(
targetState = uiState.value.unitsToShow.isEmpty(),
modifier = Modifier.padding(paddingValues)
) { noUnits ->
if (noUnits) {
SearchPlaceholder(navigateToSettingsAction = navigateToSettingsAction)
} else {
LazyColumn(Modifier.fillMaxSize()) {
uiState.value.unitsToShow.forEach { (unitGroup, listOfUnits) ->
item(unitGroup.name) {
UnitGroupHeader(Modifier.animateItemPlacement(), unitGroup)
}
items(listOfUnits, { it.unitId }) { unit ->
UnitListItem(
modifier = Modifier.animateItemPlacement(),
unit = unit,
isSelected = currentUnit == unit.unitId,
selectAction = {
selectAction(it)
viewModel.onSearchQueryChange("", true)
focusManager.clearFocus(true)
navigateUp()
},
favoriteAction = { viewModel.favoriteUnit(it) },
convertValue = convertMethod
)
}
}
}
}
}
}
}
private fun convertForSecondary(
inputValue: BigDecimal,
unitFrom: AbstractUnit,
unitTo: AbstractUnit,
formatterSymbols: FormatterSymbols
): String {
return unitFrom.convert(unitTo, inputValue, 3).toPlainString()
.formatExpression(formatterSymbols) + " "
}
private fun convertForSecondaryNumberBase(
inputValue: String,
unitFrom: AbstractUnit,
unitTo: AbstractUnit
): String {
return try {
(unitFrom as NumberBaseUnit).convertToBase(
inputValue,
(unitTo as NumberBaseUnit).base
) + " "
} catch (e: NumberFormatException) {
""
} catch (e: ClassCastException) {
""
}
}

View File

@ -1,41 +0,0 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.unitslist
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.UnitGroup
/**
* Second (unit list) screen UI state.
*
* @property favoritesOnly Whether or not show only favorite [AbstractUnit]s.
* @property unitsToShow Grouped list of [AbstractUnit]s.
* @property searchQuery Search query in search bar.
* @property shownUnitGroups All [UnitGroup]s that can be seen in chips row
* @property chosenUnitGroup Currently selected chip. Nul means that no chip is selected.
*/
data class SecondScreenUIState(
val favoritesOnly: Boolean = false,
val unitsToShow: Map<UnitGroup, List<AbstractUnit>> = emptyMap(),
val searchQuery: String = "",
val shownUnitGroups: List<UnitGroup> = listOf(),
val chosenUnitGroup: UnitGroup? = null,
val formatterSymbols: FormatterSymbols = FormatterSymbols.Spaces,
)

View File

@ -1,173 +0,0 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2022-2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.unitslist
import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols
import com.sadellie.unitto.data.database.UnitsEntity
import com.sadellie.unitto.data.database.UnitsRepository
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.units.AllUnitsRepository
import com.sadellie.unitto.data.userprefs.MainPreferences
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject
@HiltViewModel
class UnitsListViewModel @Inject constructor(
private val unitRepository: UnitsRepository,
private val allUnitsRepository: AllUnitsRepository,
private val mContext: Application,
private val userPrefsRepository: UserPreferencesRepository,
) : ViewModel() {
private val _userPrefs: StateFlow<MainPreferences> =
userPrefsRepository.mainPreferencesFlow.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5000L),
MainPreferences()
)
private val _unitsToShow = MutableStateFlow(emptyMap<UnitGroup, List<AbstractUnit>>())
private val _searchQuery = MutableStateFlow("")
private val _chosenUnitGroup: MutableStateFlow<UnitGroup?> = MutableStateFlow(null)
val mainFlow = combine(
_userPrefs,
_unitsToShow,
_searchQuery,
_chosenUnitGroup,
) { userPrefs, unitsToShow, searchQuery, chosenUnitGroup ->
return@combine SecondScreenUIState(
favoritesOnly = userPrefs.unitConverterFavoritesOnly,
unitsToShow = unitsToShow,
searchQuery = searchQuery,
chosenUnitGroup = chosenUnitGroup,
shownUnitGroups = userPrefs.shownUnitGroups,
formatterSymbols = AllFormatterSymbols.getById(userPrefs.separator)
)
}
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), SecondScreenUIState())
fun toggleFavoritesOnly(hideBrokenUnits: Boolean) {
viewModelScope.launch {
userPrefsRepository.updateUnitConverterFavoritesOnly(
!_userPrefs.value.unitConverterFavoritesOnly
)
loadUnitsToShow(hideBrokenUnits)
}
}
fun onSearchQueryChange(newValue: String, hideBrokenUnits: Boolean) {
_searchQuery.update { newValue }
loadUnitsToShow(hideBrokenUnits)
}
/**
* Changes currently selected chip. Used only when navigating
*
* @param unit Will find group for unit with this id.
*/
fun setSelectedChip(unit: String, hideBrokenUnits: Boolean) {
_chosenUnitGroup.update { allUnitsRepository.getById(unit).group }
loadUnitsToShow(hideBrokenUnits)
}
/**
* Changes currently selected chip, but acts as toggle when the given [UnitGroup] is same as
* already set [UnitGroup]. For example, if currently selected [UnitGroup] is [UnitGroup.TIME]
* and the provided [UnitGroup] is also [UnitGroup.TIME], currently selected unit will be set
* to null (toggle).
*
* @param unitGroup [UnitGroup], currently selected chip.
*/
fun toggleSelectedChip(unitGroup: UnitGroup, hideBrokenUnits: Boolean) {
val newUnitGroup = if (_chosenUnitGroup.value == unitGroup) null else unitGroup
_chosenUnitGroup.update { newUnitGroup }
loadUnitsToShow(hideBrokenUnits)
}
/**
* Filters and groups [AllUnitsRepository.allUnits] in coroutine
*
* @param hideBrokenUnits Broken units come from currencies API (basic unit is zero)
*/
private fun loadUnitsToShow(
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(
hideBrokenUnits = hideBrokenUnits,
chosenUnitGroup = _chosenUnitGroup.value,
favoritesOnly = _userPrefs.value.unitConverterFavoritesOnly,
searchQuery = _searchQuery.value,
allUnitsGroups = _userPrefs.value.shownUnitGroups,
sorting = _userPrefs.value.unitConverterSorting
)
_unitsToShow.update { unitsToShow }
}
}
}
/**
* Add or remove from favorites (changes to the opposite of current state, toggle)
*/
fun favoriteUnit(unit: AbstractUnit) {
viewModelScope.launch {
// Changing unit in list to the opposite
unit.isFavorite = !unit.isFavorite
// Updating it in database
unitRepository.insertUnits(
UnitsEntity(
unitId = unit.unitId,
isFavorite = unit.isFavorite,
pairedUnitId = unit.pairedUnit,
frequency = unit.counter
)
)
}
}
private fun loadUnitsFromDatabase() {
viewModelScope.launch(Dispatchers.IO) {
// Now we load units data from database
val allUnits = unitRepository.getAll()
allUnitsRepository.loadFromDatabase(mContext, allUnits)
}
}
init {
loadUnitsFromDatabase()
}
}

View File

@ -1,88 +0,0 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.feature.unitslist.navigation
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.units.AllUnitsRepository
import com.sadellie.unitto.feature.unitslist.LeftSideScreen
import com.sadellie.unitto.feature.unitslist.RightSideScreen
import com.sadellie.unitto.feature.unitslist.UnitsListViewModel
private const val LEFT_SIDE_ROUTE = "LEFT_SIDE_ROUTE"
private const val RIGHT_SIDE_ROUTE = "RIGHT_SIDE_ROUTE"
private const val UNIT_FROM_ARG = "UNIT_FROM_ARG"
private const val UNIT_TO_ARG = "UNIT_FROM_ARG"
private const val INPUT_ARG = "INPUT_ARG"
fun NavController.navigateToLeftSide(unitFromId: String) {
navigate("$LEFT_SIDE_ROUTE/$unitFromId")
}
fun NavController.navigateToRightSide(unitFromId: String, unitToId: String, input: String?) {
navigate("$RIGHT_SIDE_ROUTE/$unitFromId/$unitToId/$input")
}
fun NavGraphBuilder.leftScreen(
viewModel: UnitsListViewModel,
navigateUp: () -> Unit,
navigateToUnitGroups: () -> Unit,
onSelect: (AbstractUnit) -> Unit
) {
composable(
route = "$LEFT_SIDE_ROUTE/{$UNIT_FROM_ARG}"
) {
LeftSideScreen(
viewModel = viewModel,
currentUnitId = it.arguments?.getString(UNIT_FROM_ARG),
navigateUp = navigateUp,
navigateToSettingsAction = navigateToUnitGroups,
selectAction = onSelect
)
}
}
fun NavGraphBuilder.rightScreen(
viewModel: UnitsListViewModel,
navigateUp: () -> Unit,
navigateToUnitGroups: () -> Unit,
onSelect: (AbstractUnit) -> Unit
) {
composable(
route = "$RIGHT_SIDE_ROUTE/{$UNIT_FROM_ARG}/{$UNIT_TO_ARG}/{$INPUT_ARG}"
) {
val unitFromId = it.arguments?.getString(UNIT_FROM_ARG) ?: return@composable
val unitToId = it.arguments?.getString(UNIT_TO_ARG) ?: return@composable
val input = it.arguments?.getString(INPUT_ARG)
viewModel.setSelectedChip(unitFromId, true)
RightSideScreen(
viewModel = viewModel,
currentUnit = unitToId,
navigateUp = navigateUp,
navigateToSettingsAction = navigateToUnitGroups,
selectAction = onSelect,
inputValue = input,
unitFrom = AllUnitsRepository().getById(unitFromId)
)
}
}

View File

@ -17,7 +17,7 @@ comGoogleDagger = "2.47"
androidxComposeMaterialIconsExtended = "1.6.0-alpha02"
androidxDatastore = "1.0.0"
comGoogleAccompanist = "0.30.1"
androidxRoom = "2.6.0-alpha02"
androidxRoom = "2.6.0-beta01"
comSquareupMoshi = "1.15.0"
comSquareupRetrofit2 = "2.9.0"
comGithubSadellieThemmo = "1.0.0"

View File

@ -22,7 +22,6 @@ include(":data:units")
include(":core:base")
include(":core:ui")
include(":feature:converter")
include(":feature:unitslist")
include(":feature:calculator")
include(":feature:datecalculator")
include(":feature:timezone")