diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 09f308ac..c2115f51 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -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"))) diff --git a/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt b/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt index 69ab8f48..997eb391 100644 --- a/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt +++ b/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt @@ -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( diff --git a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/UnittoSearchBar.kt b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/UnittoSearchBar.kt index f269649f..55db1ee0 100644 --- a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/UnittoSearchBar.kt +++ b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/UnittoSearchBar.kt @@ -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, diff --git a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/FormatterExtensions.kt b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/FormatterExtensions.kt index b9843698..3a775d58 100644 --- a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/FormatterExtensions.kt +++ b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/FormatterExtensions.kt @@ -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 { diff --git a/core/ui/src/test/java/com/sadellie/unitto/core/ui/FormatterTest.kt b/core/ui/src/test/java/com/sadellie/unitto/core/ui/FormatterTest.kt index 28c87f7c..d82866b1 100644 --- a/core/ui/src/test/java/com/sadellie/unitto/core/ui/FormatterTest.kt +++ b/core/ui/src/test/java/com/sadellie/unitto/core/ui/FormatterTest.kt @@ -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,8−12+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()) - } } \ No newline at end of file diff --git a/data/common/src/main/java/com/sadellie/unitto/data/common/BigDecimalUtils.kt b/data/common/src/main/java/com/sadellie/unitto/data/common/BigDecimalUtils.kt index 0400b469..4354814c 100644 --- a/data/common/src/main/java/com/sadellie/unitto/data/common/BigDecimalUtils.kt +++ b/data/common/src/main/java/com/sadellie/unitto/data/common/BigDecimalUtils.kt @@ -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]. */ diff --git a/data/database/schemas/com.sadellie.unitto.data.database.UnittoDatabase/4.json b/data/database/schemas/com.sadellie.unitto.data.database.UnittoDatabase/4.json new file mode 100644 index 00000000..a37ad46f --- /dev/null +++ b/data/database/schemas/com.sadellie.unitto.data.database.UnittoDatabase/4.json @@ -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')" + ] + } +} \ No newline at end of file diff --git a/data/database/src/main/java/com/sadellie/unitto/data/database/UnitsDao.kt b/data/database/src/main/java/com/sadellie/unitto/data/database/UnitsDao.kt index 6a1175cc..5e03da1c 100644 --- a/data/database/src/main/java/com/sadellie/unitto/data/database/UnitsDao.kt +++ b/data/database/src/main/java/com/sadellie/unitto/data/database/UnitsDao.kt @@ -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 + fun getAllFlow(): Flow> @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? } diff --git a/data/database/src/main/java/com/sadellie/unitto/data/database/UnitsEntity.kt b/data/database/src/main/java/com/sadellie/unitto/data/database/UnitsEntity.kt index 83601859..8d008c0f 100644 --- a/data/database/src/main/java/com/sadellie/unitto/data/database/UnitsEntity.kt +++ b/data/database/src/main/java/com/sadellie/unitto/data/database/UnitsEntity.kt @@ -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, ) diff --git a/data/database/src/main/java/com/sadellie/unitto/data/database/UnittoDatabase.kt b/data/database/src/main/java/com/sadellie/unitto/data/database/UnittoDatabase.kt index 1c25b0d8..b1528a88 100644 --- a/data/database/src/main/java/com/sadellie/unitto/data/database/UnittoDatabase.kt +++ b/data/database/src/main/java/com/sadellie/unitto/data/database/UnittoDatabase.kt @@ -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() { diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/DefaultUnit.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/DefaultUnit.kt deleted file mode 100644 index b37a6e01..00000000 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/DefaultUnit.kt +++ /dev/null @@ -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 . - */ - -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() - } -} diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/AbstractUnit.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/unit/AbstractUnit.kt similarity index 57% rename from data/model/src/main/java/com/sadellie/unitto/data/model/AbstractUnit.kt rename to data/model/src/main/java/com/sadellie/unitto/data/model/unit/AbstractUnit.kt index 8ee9aae4..c4358942 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/AbstractUnit.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/unit/AbstractUnit.kt @@ -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 . */ -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.sortByLev(stringA: String): Sequence { +fun Sequence.filterByLev(stringA: String, context: Context): Sequence { 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>() 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.sortByLev(stringA: String): Sequence { 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) diff --git a/data/database/src/main/java/com/sadellie/unitto/data/database/UnitsRepository.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/unit/DefaultUnit.kt similarity index 51% rename from data/database/src/main/java/com/sadellie/unitto/data/database/UnitsRepository.kt rename to data/model/src/main/java/com/sadellie/unitto/data/model/unit/DefaultUnit.kt index 810f032d..359db5f6 100644 --- a/data/database/src/main/java/com/sadellie/unitto/data/database/UnitsRepository.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/unit/DefaultUnit.kt @@ -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 . */ -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 { - return unitsDao.getAll() - } -} \ No newline at end of file +interface DefaultUnit : AbstractUnit { + fun convert(unitTo: DefaultUnit, value: BigDecimal): BigDecimal +} diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/unit/NormalUnit.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/unit/NormalUnit.kt new file mode 100644 index 00000000..fb3506be --- /dev/null +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/unit/NormalUnit.kt @@ -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 . + */ + +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) + } +} diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/NumberBaseUnit.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/unit/NumberBaseUnit.kt similarity index 56% rename from data/model/src/main/java/com/sadellie/unitto/data/model/NumberBaseUnit.kt rename to data/model/src/main/java/com/sadellie/unitto/data/model/unit/NumberBaseUnit.kt index 3fc4ec25..2cc281eb 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/NumberBaseUnit.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/unit/NumberBaseUnit.kt @@ -16,28 +16,22 @@ * along with this program. If not, see . */ -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()) } - -} \ No newline at end of file +} diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/FlowRateUnit.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/unit/ReverseUnit.kt similarity index 51% rename from data/model/src/main/java/com/sadellie/unitto/data/model/FlowRateUnit.kt rename to data/model/src/main/java/com/sadellie/unitto/data/model/unit/ReverseUnit.kt index 8ae610ce..6d14c4e8 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/FlowRateUnit.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/unit/ReverseUnit.kt @@ -16,42 +16,31 @@ * along with this program. If not, see . */ -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() } } diff --git a/data/units/build.gradle.kts b/data/units/build.gradle.kts index df73e349..5e1bc74d 100644 --- a/data/units/build.gradle.kts +++ b/data/units/build.gradle.kts @@ -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) diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt deleted file mode 100644 index 4680e432..00000000 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/AllUnitsRepository.kt +++ /dev/null @@ -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 . - */ - -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 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 { - 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, - sorting: UnitsListSorting = UnitsListSorting.USAGE - ): Map> { - // Leave only shown unit groups - var units: Sequence = 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) { - 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 = 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 - } - } - } -} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/FlowUtils.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/FlowUtils.kt index 83f5f89f..cb8ea0a6 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/FlowUtils.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/FlowUtils.kt @@ -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 combine( + flow: Flow, + flow2: Flow, + flow3: Flow, + flow4: Flow, + flow5: Flow, + flow6: Flow, + transform: suspend (T1, T2, T3, T4, T5, T6) -> R, +): Flow = + 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 combine( + flow: Flow, + flow2: Flow, + flow3: Flow, + flow4: Flow, + flow5: Flow, + flow6: Flow, + flow7: Flow, + transform: suspend (T1, T2, T3, T4, T5, T6, T7) -> R, +): Flow = + 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 combine( flow: Flow, flow2: Flow, @@ -30,9 +93,18 @@ fun combine( flow6: Flow, flow7: Flow, flow8: Flow, - transform: suspend (T1, T2, T3, T4, T5, T6, T7, T8) -> R + transform: suspend (T1, T2, T3, T4, T5, T6, T7, T8) -> R, ): Flow = - 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 combine( args[7] as T8, ) } + +fun Flow.stateIn(scope: CoroutineScope, initialValue: T): StateFlow = + stateIn(scope, SharingStarted.WhileSubscribed(5000L), initialValue) diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/UnitsRepository.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/UnitsRepository.kt new file mode 100644 index 00000000..96118dd9 --- /dev/null +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/UnitsRepository.kt @@ -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 . + */ + +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 { + 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 = 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, + ): Map> { + // Leave only shown unit groups + var units: Sequence = 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 List.replace(newValue: T, block: (T) -> Boolean): List { + return map { + if (block(it)) newValue else it + } + } +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Acceleration.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Acceleration.kt index eb79cde7..c8feeef1 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Acceleration.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Acceleration.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Angle.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Angle.kt index 269f60e8..92a12dd4 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Angle.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Angle.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Area.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Area.kt index f224ca18..4a467941 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Area.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Area.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Capacitance.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Capacitance.kt deleted file mode 100644 index c865a7c8..00000000 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Capacitance.kt +++ /dev/null @@ -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 . - */ - -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 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), - ) -} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Currency.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Currency.kt index 9b9cf6a0..f6c6c6e0 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Currency.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Currency.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Data.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Data.kt index 9efc0382..b3ec3a35 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Data.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Data.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/DataTransfer.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/DataTransfer.kt index 974e0796..a642d7de 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/DataTransfer.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/DataTransfer.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/ElectrostaticCapacitance.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/ElectrostaticCapacitance.kt new file mode 100644 index 00000000..f004a9cc --- /dev/null +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/ElectrostaticCapacitance.kt @@ -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 . + */ + +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 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), + ) +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Energy.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Energy.kt index 939db2db..13e3c56e 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Energy.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Energy.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/FlowRate.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/FlowRate.kt index 962819b2..0602cb5c 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/FlowRate.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/FlowRate.kt @@ -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 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), ) } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Flux.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Flux.kt index a4a3a758..d569adc3 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Flux.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Flux.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Force.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Force.kt index 7f9d41db..8f29278e 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Force.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Force.kt @@ -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 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), ) } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Length.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Length.kt index 6710164f..530d9477 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Length.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Length.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Luminance.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Luminance.kt index 38f9aa54..928c3624 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Luminance.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Luminance.kt @@ -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 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), ) } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Mass.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Mass.kt index 731a24bb..c88c73c3 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Mass.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Mass.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/NumberBase.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/NumberBase.kt index da6bcfbf..3f9ee372 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/NumberBase.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/NumberBase.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Power.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Power.kt index abc23823..9e014f30 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Power.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Power.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Prefix.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Prefix.kt index eb7d2854..aa461b50 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Prefix.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Prefix.kt @@ -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 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), ) } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Pressure.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Pressure.kt index 9c3c1e89..2846c31a 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Pressure.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Pressure.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Speed.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Speed.kt index 5bef34cc..a4845576 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Speed.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Speed.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Temperature.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Temperature.kt index faa8895b..7b29a16d 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Temperature.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Temperature.kt @@ -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 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)) } - }, - ) -} \ No newline at end of file + 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 + } + } +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Time.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Time.kt index 29f8de12..5d696688 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Time.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Time.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Torque.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Torque.kt index b1752807..600170c4 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Torque.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Torque.kt @@ -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 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), ) } diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Volume.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Volume.kt index 51cac9e4..a191a073 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Volume.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/collections/Volume.kt @@ -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 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), ) -} \ No newline at end of file +} diff --git a/data/units/src/main/java/com/sadellie/unitto/data/units/remote/CurrencyApiService.kt b/data/units/src/main/java/com/sadellie/unitto/data/units/remote/CurrencyApiService.kt index 642bc5db..95383a9e 100644 --- a/data/units/src/main/java/com/sadellie/unitto/data/units/remote/CurrencyApiService.kt +++ b/data/units/src/main/java/com/sadellie/unitto/data/units/remote/CurrencyApiService.kt @@ -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) } } diff --git a/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsRepositoryTest.kt b/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsRepositoryTest.kt deleted file mode 100644 index ab6b2a74..00000000 --- a/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsRepositoryTest.kt +++ /dev/null @@ -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 . - */ - -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 = 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 - ) - } -} diff --git a/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsTest.kt b/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsTest.kt index e7d562b0..93f0bfea 100644 --- a/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsTest.kt +++ b/data/units/src/test/java/com/sadellie/unitto/data/units/AllUnitsTest.kt @@ -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> = 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) diff --git a/data/units/src/test/java/com/sadellie/unitto/data/units/LevenshteinFilterAndSortTest.kt b/data/units/src/test/java/com/sadellie/unitto/data/units/LevenshteinFilterAndSortTest.kt index 95d56a27..f6acf9d8 100644 --- a/data/units/src/test/java/com/sadellie/unitto/data/units/LevenshteinFilterAndSortTest.kt +++ b/data/units/src/test/java/com/sadellie/unitto/data/units/LevenshteinFilterAndSortTest.kt @@ -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 = 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(), @@ -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"), diff --git a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt index 47b0da01..40f43338 100644 --- a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt +++ b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt @@ -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 = dataStore.data + val mainPrefsFlow: Flow = 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 } } diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorViewModel.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorViewModel.kt index 2517823a..234af7fa 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorViewModel.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorViewModel.kt @@ -55,7 +55,7 @@ internal class CalculatorViewModel @Inject constructor( private val calculatorHistoryRepository: CalculatorHistoryRepository, ) : ViewModel() { private val _userPrefs: StateFlow = - userPrefsRepository.mainPreferencesFlow.stateIn( + userPrefsRepository.mainPrefsFlow.stateIn( viewModelScope, SharingStarted.WhileSubscribed(5000L), MainPreferences() diff --git a/feature/converter/build.gradle.kts b/feature/converter/build.gradle.kts index 296ff6c4..a522f869 100644 --- a/feature/converter/build.gradle.kts +++ b/feature/converter/build.gradle.kts @@ -16,6 +16,8 @@ * along with this program. If not, see . */ +@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) diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterScreen.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterScreen.kt index 6cd28d27..58d601b0 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterScreen.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterScreen.kt @@ -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 = {}, ) } diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterUIState.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterUIState.kt index 4dc6d788..0976a50d 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterUIState.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterUIState.kt @@ -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() + + 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") } diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterViewModel.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterViewModel.kt index 93d0ceec..888badde 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterViewModel.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterViewModel.kt @@ -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 = MutableStateFlow(null) + private val _input = MutableStateFlow(TextFieldValue()) + private val _calculation = MutableStateFlow(null) + private val _result = MutableStateFlow(ConverterResult.Loading) + private val _unitFrom = MutableStateFlow(null) + private val _unitTo = MutableStateFlow(null) - /** - * Unit on the right, the one we convert to. Initially null, meaning we didn't restore it yet. - */ - private val _unitTo: MutableStateFlow = 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 = MutableStateFlow(TextFieldValue()) - - /** - * Calculation result. Null when [_input] is not an expression. - */ - private val _calculated: MutableStateFlow = MutableStateFlow(null) - - /** - * Conversion result. - */ - private val _result: MutableStateFlow = MutableStateFlow(ConversionResult.Loading) - - /** - * True when loading something from network. - */ - private val _showLoading: MutableStateFlow = MutableStateFlow(false) - - /** - * True if there was error while loading data. - */ - private val _showError: MutableStateFlow = MutableStateFlow(false) - - /** - * Current state of UI. - */ - val uiState: StateFlow = combine( + val converterUiState: StateFlow = 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, + ) = 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, + ) = 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) + } } } diff --git a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/LeftSideScreen.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/LeftSideScreen.kt similarity index 53% rename from feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/LeftSideScreen.kt rename to feature/converter/src/main/java/com/sadellie/unitto/feature/converter/LeftSideScreen.kt index 6df6b26c..7f95768a 100644 --- a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/LeftSideScreen.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/LeftSideScreen.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -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 = {} + ) } diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/LeftSideUIState.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/LeftSideUIState.kt new file mode 100644 index 00000000..ae21917e --- /dev/null +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/LeftSideUIState.kt @@ -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 . + */ + +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>? = null, + val favorites: Boolean = false, + val shownUnitGroups: List = emptyList(), + val unitGroup: UnitGroup? = unitFrom?.group, + val sorting: UnitsListSorting = UnitsListSorting.USAGE, +) diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/RightSideScreen.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/RightSideScreen.kt new file mode 100644 index 00000000..9ef3d1de --- /dev/null +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/RightSideScreen.kt @@ -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 . + */ + +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 = {} + ) +} + diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/RightSideUIState.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/RightSideUIState.kt new file mode 100644 index 00000000..c57aa156 --- /dev/null +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/RightSideUIState.kt @@ -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 . + */ + +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>? = 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, +) diff --git a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/UnitListItem.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/BasicUnitListItem.kt similarity index 54% rename from feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/UnitListItem.kt rename to feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/BasicUnitListItem.kt index 29fbb3d7..4e1e41bf 100644 --- a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/UnitListItem.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/BasicUnitListItem.kt @@ -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 . */ -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)}" -) diff --git a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/ChipsRow.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ChipsRow.kt similarity index 96% rename from feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/ChipsRow.kt rename to feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ChipsRow.kt index 2261fbb0..0631167e 100644 --- a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/ChipsRow.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ChipsRow.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -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 = 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( diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ConverterKeyboard.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ConverterKeyboard.kt index 38d8e94e..e239853c 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ConverterKeyboard.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/ConverterKeyboard.kt @@ -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() + ) +} diff --git a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/FavoritesButton.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/FavoritesButton.kt similarity index 95% rename from feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/FavoritesButton.kt rename to feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/FavoritesButton.kt index 51b7fbc7..fdf78d25 100644 --- a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/FavoritesButton.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/FavoritesButton.kt @@ -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 . */ -package com.sadellie.unitto.feature.unitslist.components +package com.sadellie.unitto.feature.converter.components import androidx.compose.animation.AnimatedContent import androidx.compose.animation.SizeTransform diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/MyTextField.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/MyTextField.kt deleted file mode 100644 index e69de29b..00000000 diff --git a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/SearchPlaceholder.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/SearchPlaceholder.kt similarity index 91% rename from feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/SearchPlaceholder.kt rename to feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/SearchPlaceholder.kt index c0c72c38..006bfab4 100644 --- a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/SearchPlaceholder.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/SearchPlaceholder.kt @@ -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 . */ -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( diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/TopScreen.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/TopScreen.kt deleted file mode 100644 index 0c5abe2b..00000000 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/TopScreen.kt +++ /dev/null @@ -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 . - */ - -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, - ) - } - } -} diff --git a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/UnitGroupHeader.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/UnitGroupHeader.kt similarity index 95% rename from feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/UnitGroupHeader.kt rename to feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/UnitGroupHeader.kt index cc3d3e3d..97a3dcfe 100644 --- a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/components/UnitGroupHeader.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/UnitGroupHeader.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -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 diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/UnitSelectionButton.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/UnitSelectionButton.kt index 40097f47..36380b46 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/UnitSelectionButton.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/components/UnitSelectionButton.kt @@ -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 diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/navigation/ConverterNavigation.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/navigation/ConverterNavigation.kt index 0dbdb170..db7a6161 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/navigation/ConverterNavigation.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/navigation/ConverterNavigation.kt @@ -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(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(parentEntry) + + LeftSideRoute( + viewModel = parentViewModel, + navigateUp = navController::navigateUp, + navigateToUnitGroups = navigateToUnitGroups + ) + } + + composable(RIGHT) { backStackEntry -> + val parentEntry = remember(backStackEntry) { + navController.getBackStackEntry(graph) + } + + val parentViewModel = hiltViewModel(parentEntry) + + RightSideRoute( + viewModel = parentViewModel, + navigateUp = navController::navigateUp, + navigateToUnitGroups = navigateToUnitGroups ) } } diff --git a/feature/converter/src/test/java/com/sadellie/unitto/feature/converter/ConverterUIStateKtTest.kt b/feature/converter/src/test/java/com/sadellie/unitto/feature/converter/ConverterUIStateKtTest.kt new file mode 100644 index 00000000..79fcee6a --- /dev/null +++ b/feature/converter/src/test/java/com/sadellie/unitto/feature/converter/ConverterUIStateKtTest.kt @@ -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 . + */ + +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()) + } +} diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/formatting/FormattingViewModel.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/formatting/FormattingViewModel.kt index a72de138..e091d4db 100644 --- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/formatting/FormattingViewModel.kt +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/formatting/FormattingViewModel.kt @@ -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 -> diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/unitgroups/UnitGroupsViewModel.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/unitgroups/UnitGroupsViewModel.kt index 229f6119..26fdf74d 100644 --- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/unitgroups/UnitGroupsViewModel.kt +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/unitgroups/UnitGroupsViewModel.kt @@ -87,7 +87,7 @@ class UnitGroupsViewModel @Inject constructor( init { viewModelScope.launch { unitGroupsRepository.updateShownGroups( - userPrefsRepository.mainPreferencesFlow.first().shownUnitGroups + userPrefsRepository.mainPrefsFlow.first().shownUnitGroups ) } } diff --git a/feature/timezone/src/main/java/com/sadellie/unitto/timezone/AddTimeZoneScreen.kt b/feature/timezone/src/main/java/com/sadellie/unitto/timezone/AddTimeZoneScreen.kt index 73286280..11f41f5c 100644 --- a/feature/timezone/src/main/java/com/sadellie/unitto/timezone/AddTimeZoneScreen.kt +++ b/feature/timezone/src/main/java/com/sadellie/unitto/timezone/AddTimeZoneScreen.kt @@ -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() diff --git a/feature/timezone/src/main/java/com/sadellie/unitto/timezone/AddTimeZoneUIState.kt b/feature/timezone/src/main/java/com/sadellie/unitto/timezone/AddTimeZoneUIState.kt index affe3222..6b997383 100644 --- a/feature/timezone/src/main/java/com/sadellie/unitto/timezone/AddTimeZoneUIState.kt +++ b/feature/timezone/src/main/java/com/sadellie/unitto/timezone/AddTimeZoneUIState.kt @@ -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 = emptyList(), val userTime: ZonedDateTime? = null, ) diff --git a/feature/timezone/src/main/java/com/sadellie/unitto/timezone/AddTimeZoneViewModel.kt b/feature/timezone/src/main/java/com/sadellie/unitto/timezone/AddTimeZoneViewModel.kt index c37032a2..73c2778f 100644 --- a/feature/timezone/src/main/java/com/sadellie/unitto/timezone/AddTimeZoneViewModel.kt +++ b/feature/timezone/src/main/java/com/sadellie/unitto/timezone/AddTimeZoneViewModel.kt @@ -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.now()) - private val _query = MutableStateFlow("") + private val _query = MutableStateFlow(TextFieldValue()) private val _filteredTimeZones = MutableStateFlow(emptyList()) 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 { diff --git a/feature/unitslist/.gitignore b/feature/unitslist/.gitignore deleted file mode 100644 index 42afabfd..00000000 --- a/feature/unitslist/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/feature/unitslist/build.gradle.kts b/feature/unitslist/build.gradle.kts deleted file mode 100644 index 065310e6..00000000 --- a/feature/unitslist/build.gradle.kts +++ /dev/null @@ -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 . -*/ - -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"))) -} \ No newline at end of file diff --git a/feature/unitslist/consumer-rules.pro b/feature/unitslist/consumer-rules.pro deleted file mode 100644 index e69de29b..00000000 diff --git a/feature/unitslist/src/main/AndroidManifest.xml b/feature/unitslist/src/main/AndroidManifest.xml deleted file mode 100644 index 7bdbce91..00000000 --- a/feature/unitslist/src/main/AndroidManifest.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/RightSideScreen.kt b/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/RightSideScreen.kt deleted file mode 100644 index 30484866..00000000 --- a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/RightSideScreen.kt +++ /dev/null @@ -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 . - */ - -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) { - "" - } -} diff --git a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/SecondScreenUIState.kt b/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/SecondScreenUIState.kt deleted file mode 100644 index 57e15201..00000000 --- a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/SecondScreenUIState.kt +++ /dev/null @@ -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 . - */ - -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> = emptyMap(), - val searchQuery: String = "", - val shownUnitGroups: List = listOf(), - val chosenUnitGroup: UnitGroup? = null, - val formatterSymbols: FormatterSymbols = FormatterSymbols.Spaces, -) diff --git a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/UnitsListViewModel.kt b/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/UnitsListViewModel.kt deleted file mode 100644 index 01b5a594..00000000 --- a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/UnitsListViewModel.kt +++ /dev/null @@ -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 . - */ - -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 = - userPrefsRepository.mainPreferencesFlow.stateIn( - viewModelScope, - SharingStarted.WhileSubscribed(5000L), - MainPreferences() - ) - private val _unitsToShow = MutableStateFlow(emptyMap>()) - private val _searchQuery = MutableStateFlow("") - private val _chosenUnitGroup: MutableStateFlow = 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() - } -} diff --git a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/navigation/UnitsListNavigation.kt b/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/navigation/UnitsListNavigation.kt deleted file mode 100644 index 2fea26fe..00000000 --- a/feature/unitslist/src/main/java/com/sadellie/unitto/feature/unitslist/navigation/UnitsListNavigation.kt +++ /dev/null @@ -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 . - */ - -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) - ) - } -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 85dca64c..1ae6ecf9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -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" diff --git a/settings.gradle.kts b/settings.gradle.kts index fda17c24..5496d546 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -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")