From 263a1139dcc1f8afe18a2e82f86fd94f7aa919df Mon Sep 17 00:00:00 2001 From: Sad Ellie Date: Mon, 12 Feb 2024 22:12:07 +0300 Subject: [PATCH] Refactor FormatterSymbols closes #90 --- .../{Separator.kt => FormatterSymbols.kt} | 16 +- .../com/sadellie/unitto/core/base/Token.kt | 4 + core/base/src/main/res/values/strings.xml | 2 + .../unitto/core/base/SeparatorTest.kt | 45 --- .../sadellie/unitto/core/base/TokenTest.kt | 10 +- .../common/textfield/ClipboardManagerExt.kt | 1 + .../common/textfield/ExpressionTransformer.kt | 1 + .../common/textfield/FixedInputTextFIeld.kt | 1 + .../common/textfield/FormatterExtensions.kt | 1 + .../ui/common/textfield/FormatterSymbols.kt | 46 --- .../ui/common/textfield/InputTextField.kt | 1 + .../core/ui/CleanAndFilterExpression.kt | 26 +- .../core/ui/ExpressionTransformerTest.kt | 5 +- .../unitto/core/ui/FormatterExpressionTest.kt | 9 +- .../repository/UserPreferencesRepository.kt | 2 +- .../model/userprefs/AddSubtractPreferences.kt | 4 +- .../model/userprefs/BodyMassPreferences.kt | 4 +- .../model/userprefs/CalculatorPreferences.kt | 4 +- .../model/userprefs/ConverterPreferences.kt | 3 +- .../model/userprefs/FormattingPreferences.kt | 4 +- .../unitto/data/userprefs/PreferenceExt.kt | 20 +- .../unitto/data/userprefs/PreferenceModels.kt | 11 +- .../unitto/data/userprefs/PrefsKeys.kt | 2 + ...es.kt => UserPreferencesRepositoryImpl.kt} | 18 +- .../unitto/feature/bodymass/BodyMassScreen.kt | 5 +- .../feature/bodymass/BodyMassViewModel.kt | 3 +- .../unitto/feature/bodymass/UIState.kt | 2 +- .../bodymass/components/BodyMassResult.kt | 5 +- .../calculator/CalculatorScreenTest.kt | 7 +- .../feature/calculator/CalculatorScreen.kt | 5 +- .../feature/calculator/CalculatorUIState.kt | 2 +- .../feature/calculator/CalculatorViewModel.kt | 3 +- .../components/CalculatorKeyboard.kt | 13 +- .../calculator/components/HistoryList.kt | 5 +- .../feature/calculator/components/TextBox.kt | 2 +- .../feature/converter/ConverterScreen.kt | 4 +- .../feature/converter/ConverterUIState.kt | 2 +- .../feature/converter/ConverterViewModel.kt | 3 +- .../feature/converter/UnitSelectorUIState.kt | 2 +- .../converter/UnitSelectorViewModel.kt | 3 +- .../feature/converter/UnitToSelectorScreen.kt | 5 +- .../converter/components/ConverterKeyboard.kt | 7 +- .../converter/ConverterUIStateKtTest.kt | 5 +- .../addsubtract/AddSubtractUIState.kt | 5 +- .../addsubtract/AddSubtractViewModel.kt | 3 +- .../difference/DateDifferencePage.kt | 5 +- .../difference/DateDifferenceViewModel.kt | 3 +- .../difference/DifferenceUIState.kt | 2 +- .../feature/glance/glance/CalculatorWidget.kt | 5 +- .../calculator/CalculatorSettingsScreen.kt | 5 +- .../converter/ConverterSettingsScreen.kt | 5 +- .../settings/formatting/FormattingScreen.kt | 286 ++++++++++-------- .../settings/formatting/FormattingUIState.kt | 3 +- .../formatting/FormattingViewModel.kt | 10 +- 54 files changed, 323 insertions(+), 332 deletions(-) rename core/base/src/main/java/com/sadellie/unitto/core/base/{Separator.kt => FormatterSymbols.kt} (73%) delete mode 100644 core/base/src/test/java/com/sadellie/unitto/core/base/SeparatorTest.kt delete mode 100644 core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/FormatterSymbols.kt rename data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/{UserPreferences.kt => UserPreferencesRepositoryImpl.kt} (94%) diff --git a/core/base/src/main/java/com/sadellie/unitto/core/base/Separator.kt b/core/base/src/main/java/com/sadellie/unitto/core/base/FormatterSymbols.kt similarity index 73% rename from core/base/src/main/java/com/sadellie/unitto/core/base/Separator.kt rename to core/base/src/main/java/com/sadellie/unitto/core/base/FormatterSymbols.kt index b5559383..8281ec1d 100644 --- a/core/base/src/main/java/com/sadellie/unitto/core/base/Separator.kt +++ b/core/base/src/main/java/com/sadellie/unitto/core/base/FormatterSymbols.kt @@ -1,6 +1,6 @@ /* * Unitto is a calculator for Android - * Copyright (c) 2022-2024 Elshan Agaev + * Copyright (c) 2024 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 @@ -19,10 +19,12 @@ package com.sadellie.unitto.core.base /** - * Separators mean symbols that separate fractional part + * Formatter symbols. Always use [Token]. + * + * @property grouping Symbol fpr thousands separator. + * @property fractional Symbol decimal separator. */ -object Separator { - const val SPACE = 0 - const val PERIOD = 1 - const val COMMA = 2 -} +data class FormatterSymbols( + val grouping: String, + val fractional: String, +) diff --git a/core/base/src/main/java/com/sadellie/unitto/core/base/Token.kt b/core/base/src/main/java/com/sadellie/unitto/core/base/Token.kt index fbc9f5d6..d7ed1d75 100644 --- a/core/base/src/main/java/com/sadellie/unitto/core/base/Token.kt +++ b/core/base/src/main/java/com/sadellie/unitto/core/base/Token.kt @@ -20,6 +20,10 @@ package com.sadellie.unitto.core.base @Suppress("ObjectPropertyName") object Token { + const val SPACE = " " + const val PERIOD = "." + const val COMMA = "," + object Digit { const val _1 = "1" const val _2 = "2" diff --git a/core/base/src/main/res/values/strings.xml b/core/base/src/main/res/values/strings.xml index dc3ef0bb..c9818640 100644 --- a/core/base/src/main/res/values/strings.xml +++ b/core/base/src/main/res/values/strings.xml @@ -245,6 +245,7 @@ Alternatively you can use "Export" --> Currency rates are updated daily. There\'s no real-time market monitoring in the app Wrong currency rates? Dark + Decimal separator Disable unit group Display App look and feel @@ -301,6 +302,7 @@ Maybe this can be labeled better? Let me know. It should be something that can d Use system font for texts in app Terms and Conditions Third party licenses + Thousands separator Settings Translate this app Join POEditor project to help diff --git a/core/base/src/test/java/com/sadellie/unitto/core/base/SeparatorTest.kt b/core/base/src/test/java/com/sadellie/unitto/core/base/SeparatorTest.kt deleted file mode 100644 index cf101bda..00000000 --- a/core/base/src/test/java/com/sadellie/unitto/core/base/SeparatorTest.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Unitto is a calculator for Android - * Copyright (c) 2023-2024 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.core.base - -import org.junit.Assert -import org.junit.Test - -class SeparatorTest { - - @Test - fun testExists() { - Assert.assertNotNull(Separator) - } - - @Test - fun testSeparatorSpace() { - Assert.assertEquals(0, Separator.SPACE) - } - - @Test - fun testSeparatorPeriod() { - Assert.assertEquals(1, Separator.PERIOD) - } - - @Test - fun testSeparatorComma() { - Assert.assertEquals(2, Separator.COMMA) - } -} \ No newline at end of file diff --git a/core/base/src/test/java/com/sadellie/unitto/core/base/TokenTest.kt b/core/base/src/test/java/com/sadellie/unitto/core/base/TokenTest.kt index 376d25d7..63f7fa3d 100644 --- a/core/base/src/test/java/com/sadellie/unitto/core/base/TokenTest.kt +++ b/core/base/src/test/java/com/sadellie/unitto/core/base/TokenTest.kt @@ -22,6 +22,14 @@ import org.junit.Assert import org.junit.Test class TokenTest { + + @Test + fun testFormatterSymbols() { + Assert.assertEquals(" ", Token.SPACE) + Assert.assertEquals(".", Token.PERIOD) + Assert.assertEquals(",", Token.COMMA) + } + @Test fun testDigit() { Assert.assertEquals("1234567890", Token.Digit.all.joinToString("")) @@ -126,7 +134,7 @@ class TokenTest { "e", ).joinToString("") - Assert.assertEquals("1234567890.$operator$func$consts", Token.expressionTokens.joinToString("")) + Assert.assertEquals("1234567890.$operator$func${consts}E", Token.expressionTokens.joinToString("")) } @Test diff --git a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/ClipboardManagerExt.kt b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/ClipboardManagerExt.kt index 600d5efb..a11ef8e8 100644 --- a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/ClipboardManagerExt.kt +++ b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/ClipboardManagerExt.kt @@ -21,6 +21,7 @@ package com.sadellie.unitto.core.ui.common.textfield import android.content.ClipData import androidx.compose.ui.platform.ClipboardManager import androidx.compose.ui.text.AnnotatedString +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.base.Token /** diff --git a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/ExpressionTransformer.kt b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/ExpressionTransformer.kt index ea9fa187..2c0812b9 100644 --- a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/ExpressionTransformer.kt +++ b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/ExpressionTransformer.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.input.OffsetMapping import androidx.compose.ui.text.input.TransformedText import androidx.compose.ui.text.input.VisualTransformation +import com.sadellie.unitto.core.base.FormatterSymbols class ExpressionTransformer(private val formatterSymbols: FormatterSymbols) : VisualTransformation { diff --git a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/FixedInputTextFIeld.kt b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/FixedInputTextFIeld.kt index e7306ff8..79a37aac 100644 --- a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/FixedInputTextFIeld.kt +++ b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/FixedInputTextFIeld.kt @@ -35,6 +35,7 @@ import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.style.TextAlign +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.ui.theme.LocalNumberTypography @Composable 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 75bd31ef..cbf6a1ae 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,6 +18,7 @@ package com.sadellie.unitto.core.ui.common.textfield +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.base.Token private val numbersRegex by lazy { Regex("[\\d.]+") } diff --git a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/FormatterSymbols.kt b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/FormatterSymbols.kt deleted file mode 100644 index a1462edd..00000000 --- a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/FormatterSymbols.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Unitto is a calculator for Android - * Copyright (c) 2023-2024 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.core.ui.common.textfield - -import com.sadellie.unitto.core.base.Separator - -sealed class FormatterSymbols(val grouping: String, val fractional: String) { - data object Spaces : FormatterSymbols(" ", ".") - data object Period : FormatterSymbols(".", ",") - data object Comma : FormatterSymbols(",", ".") -} - -object AllFormatterSymbols { - private val allFormatterSymbols by lazy { - hashMapOf( - Separator.SPACE to FormatterSymbols.Spaces, - Separator.PERIOD to FormatterSymbols.Period, - Separator.COMMA to FormatterSymbols.Comma - ) - } - - /** - * Defaults to [FormatterSymbols.Spaces] if not found. - * - * @see Separator - */ - fun getById(separator: Int): FormatterSymbols { - return allFormatterSymbols.getOrElse(separator) { FormatterSymbols.Spaces } - } -} diff --git a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/InputTextField.kt b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/InputTextField.kt index 4ebc36b5..c8ce2e52 100644 --- a/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/InputTextField.kt +++ b/core/ui/src/main/java/com/sadellie/unitto/core/ui/common/textfield/InputTextField.kt @@ -44,6 +44,7 @@ import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.TextUnit +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.ui.common.autosize.AutoSizeTextStyleBox import com.sadellie.unitto.core.ui.theme.LocalNumberTypography diff --git a/core/ui/src/test/java/com/sadellie/unitto/core/ui/CleanAndFilterExpression.kt b/core/ui/src/test/java/com/sadellie/unitto/core/ui/CleanAndFilterExpression.kt index 147e7a97..0fc30be9 100644 --- a/core/ui/src/test/java/com/sadellie/unitto/core/ui/CleanAndFilterExpression.kt +++ b/core/ui/src/test/java/com/sadellie/unitto/core/ui/CleanAndFilterExpression.kt @@ -18,40 +18,44 @@ package com.sadellie.unitto.core.ui -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols +import com.sadellie.unitto.core.base.FormatterSymbols +import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.ui.common.textfield.clearAndFilterExpression import org.junit.Assert.assertEquals import org.junit.Test class CleanAndFilterExpression { + + private val formatterSymbols = FormatterSymbols(Token.COMMA, Token.PERIOD) + @Test fun noAdditionalSymbols() { - assertEquals("123", "123".clearAndFilterExpression(FormatterSymbols.Comma)) - assertEquals("123.456", "123.456".clearAndFilterExpression(FormatterSymbols.Comma)) + assertEquals("123", "123".clearAndFilterExpression(formatterSymbols)) + assertEquals("123.456", "123.456".clearAndFilterExpression(formatterSymbols)) } @Test fun hasFormatterSymbol() { - assertEquals("123456", "123,456".clearAndFilterExpression(FormatterSymbols.Comma)) - assertEquals("123456.789", "123,456.789".clearAndFilterExpression(FormatterSymbols.Comma)) + assertEquals("123456", "123,456".clearAndFilterExpression(formatterSymbols)) + assertEquals("123456.789", "123,456.789".clearAndFilterExpression(formatterSymbols)) } @Test fun hasWrongFormatterSymbol() { - assertEquals("123456", "123 456".clearAndFilterExpression(FormatterSymbols.Comma)) - assertEquals("123456.789", "123 456.789".clearAndFilterExpression(FormatterSymbols.Comma)) + assertEquals("123456", "123 456".clearAndFilterExpression(formatterSymbols)) + assertEquals("123456.789", "123 456.789".clearAndFilterExpression(formatterSymbols)) } @Test fun fractionExpression() { - assertEquals("1600+1234÷56789", "1,600 1234⁄56789".clearAndFilterExpression(FormatterSymbols.Comma)) - assertEquals("123456.789+1234÷56789", "123,456.789 1234⁄56789".clearAndFilterExpression(FormatterSymbols.Comma)) + assertEquals("1600+1234÷56789", "1,600 1234⁄56789".clearAndFilterExpression(formatterSymbols)) + assertEquals("123456.789+1234÷56789", "123,456.789 1234⁄56789".clearAndFilterExpression(formatterSymbols)) } @Test fun garbage() { // 'e' is a known symbol - assertEquals("eeee−123", "pee pee poo poo -123".clearAndFilterExpression(FormatterSymbols.Comma)) - assertEquals("eeee−123.456", "pee pee poo poo -123.456".clearAndFilterExpression(FormatterSymbols.Comma)) + assertEquals("eeee−123", "pee pee poo poo -123".clearAndFilterExpression(formatterSymbols)) + assertEquals("eeee−123.456", "pee pee poo poo -123.456".clearAndFilterExpression(formatterSymbols)) } } diff --git a/core/ui/src/test/java/com/sadellie/unitto/core/ui/ExpressionTransformerTest.kt b/core/ui/src/test/java/com/sadellie/unitto/core/ui/ExpressionTransformerTest.kt index cc86d390..6cb5bc56 100644 --- a/core/ui/src/test/java/com/sadellie/unitto/core/ui/ExpressionTransformerTest.kt +++ b/core/ui/src/test/java/com/sadellie/unitto/core/ui/ExpressionTransformerTest.kt @@ -18,14 +18,15 @@ package com.sadellie.unitto.core.ui +import com.sadellie.unitto.core.base.FormatterSymbols +import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.ui.common.textfield.ExpressionTransformer -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols import org.junit.Assert.assertEquals import org.junit.Test class ExpressionTransformerTest { - private val expr = ExpressionTransformer(FormatterSymbols.Comma) + private val expr = ExpressionTransformer(FormatterSymbols(Token.COMMA, Token.PERIOD)) // Use "|" for cursor private fun origToTrans(orig: String, trans: String) { diff --git a/core/ui/src/test/java/com/sadellie/unitto/core/ui/FormatterExpressionTest.kt b/core/ui/src/test/java/com/sadellie/unitto/core/ui/FormatterExpressionTest.kt index 6179d129..038e33fa 100644 --- a/core/ui/src/test/java/com/sadellie/unitto/core/ui/FormatterExpressionTest.kt +++ b/core/ui/src/test/java/com/sadellie/unitto/core/ui/FormatterExpressionTest.kt @@ -18,7 +18,8 @@ package com.sadellie.unitto.core.ui -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols +import com.sadellie.unitto.core.base.FormatterSymbols +import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.ui.common.textfield.formatExpression import org.junit.Assert.assertEquals import org.junit.Test @@ -40,7 +41,7 @@ class FormatterExpressionTest { @Test fun setSeparatorSpaces() { - fun String.format(): String = formatExpression(FormatterSymbols.Spaces) + fun String.format(): String = formatExpression(FormatterSymbols(Token.SPACE, Token.PERIOD)) assertEquals("123E+21", ENG_VALUE.format()) assertEquals("123.3E+21", ENG_VALUE_FRACTIONAL.format()) assertEquals("123E+21+(123 456.789)", ENG_VALUE_EXPRESSION.format()) @@ -57,7 +58,7 @@ class FormatterExpressionTest { @Test fun setSeparatorComma() { - fun String.format(): String = formatExpression(FormatterSymbols.Comma) + fun String.format(): String = formatExpression(FormatterSymbols(Token.COMMA, Token.PERIOD)) assertEquals("123E+21", ENG_VALUE.format()) assertEquals("123.3E+21", ENG_VALUE_FRACTIONAL.format()) assertEquals("123E+21+(123,456.789)", ENG_VALUE_EXPRESSION.format()) @@ -74,7 +75,7 @@ class FormatterExpressionTest { @Test fun setSeparatorPeriod() { - fun String.format(): String = formatExpression(FormatterSymbols.Period) + fun String.format(): String = formatExpression(FormatterSymbols(Token.PERIOD, Token.COMMA)) assertEquals("123E+21", ENG_VALUE.format()) assertEquals("123,3E+21", ENG_VALUE_FRACTIONAL.format()) assertEquals("123E+21+(123.456,789)", ENG_VALUE_EXPRESSION.format()) diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/repository/UserPreferencesRepository.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/repository/UserPreferencesRepository.kt index a88a5dbd..d1304343 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/repository/UserPreferencesRepository.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/repository/UserPreferencesRepository.kt @@ -51,7 +51,7 @@ interface UserPreferencesRepository { suspend fun updateDigitsPrecision(precision: Int) - suspend fun updateSeparator(separator: Int) + suspend fun updateFormatterSymbols(grouping: String, fractional: String) suspend fun updateOutputFormat(outputFormat: Int) diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/AddSubtractPreferences.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/AddSubtractPreferences.kt index 4a86b10f..25684b2a 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/AddSubtractPreferences.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/AddSubtractPreferences.kt @@ -18,6 +18,8 @@ package com.sadellie.unitto.data.model.userprefs +import com.sadellie.unitto.core.base.FormatterSymbols + interface AddSubtractPreferences{ - val separator: Int + val formatterSymbols: FormatterSymbols } diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/BodyMassPreferences.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/BodyMassPreferences.kt index 8a389033..b841cdf3 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/BodyMassPreferences.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/BodyMassPreferences.kt @@ -18,6 +18,8 @@ package com.sadellie.unitto.data.model.userprefs +import com.sadellie.unitto.core.base.FormatterSymbols + interface BodyMassPreferences{ - val separator: Int + val formatterSymbols: FormatterSymbols } diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/CalculatorPreferences.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/CalculatorPreferences.kt index c4aa4611..44f063ae 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/CalculatorPreferences.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/CalculatorPreferences.kt @@ -18,9 +18,11 @@ package com.sadellie.unitto.data.model.userprefs +import com.sadellie.unitto.core.base.FormatterSymbols + interface CalculatorPreferences { val radianMode: Boolean - val separator: Int + val formatterSymbols: FormatterSymbols val middleZero: Boolean val acButton: Boolean val partialHistoryView: Boolean diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/ConverterPreferences.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/ConverterPreferences.kt index b4526f6d..bde5dbd1 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/ConverterPreferences.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/ConverterPreferences.kt @@ -18,11 +18,12 @@ package com.sadellie.unitto.data.model.userprefs +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.data.model.UnitGroup import com.sadellie.unitto.data.model.UnitsListSorting interface ConverterPreferences { - val separator: Int + val formatterSymbols: FormatterSymbols val middleZero: Boolean val acButton: Boolean val precision: Int diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/FormattingPreferences.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/FormattingPreferences.kt index b39dce0f..dcbbb3d8 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/FormattingPreferences.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/FormattingPreferences.kt @@ -18,8 +18,10 @@ package com.sadellie.unitto.data.model.userprefs +import com.sadellie.unitto.core.base.FormatterSymbols + interface FormattingPreferences{ val digitsPrecision: Int - val separator: Int + val formatterSymbols: FormatterSymbols val outputFormat: Int } diff --git a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceExt.kt b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceExt.kt index 7e222bb3..15e54fbd 100644 --- a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceExt.kt +++ b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceExt.kt @@ -19,8 +19,9 @@ package com.sadellie.unitto.data.userprefs import androidx.datastore.preferences.core.Preferences +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.base.OutputFormat -import com.sadellie.unitto.core.base.Separator +import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.base.TopLevelDestinations import com.sadellie.unitto.data.converter.UnitID import com.sadellie.unitto.data.model.UnitGroup @@ -76,8 +77,21 @@ internal fun Preferences.getRadianMode(): Boolean { return this[PrefsKeys.RADIAN_MODE] ?: true } -internal fun Preferences.getSeparator(): Int { - return this[PrefsKeys.SEPARATOR] ?: Separator.SPACE +internal fun Preferences.getFormatterSymbols(): FormatterSymbols { + val grouping = this[PrefsKeys.FORMATTER_GROUPING] + val fractional = this[PrefsKeys.FORMATTER_FRACTIONAL] + + // Updating from older version or fresh install + // TODO Remove in the future + if ((grouping == null) or (fractional == null)) { + return when(this[PrefsKeys.SEPARATOR] ?: 0) { + 0 -> FormatterSymbols(Token.SPACE, Token.PERIOD) + 1 -> FormatterSymbols(Token.PERIOD, Token.COMMA) + else -> FormatterSymbols(Token.COMMA, Token.PERIOD) + } + } + + return FormatterSymbols(grouping ?: Token.SPACE, fractional ?: Token.PERIOD) } internal fun Preferences.getMiddleZero(): Boolean { diff --git a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceModels.kt b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceModels.kt index 6b152cde..53bfaa16 100644 --- a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceModels.kt +++ b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceModels.kt @@ -18,6 +18,7 @@ package com.sadellie.unitto.data.userprefs +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.data.model.UnitGroup import com.sadellie.unitto.data.model.UnitsListSorting import com.sadellie.unitto.data.model.userprefs.AboutPreferences @@ -53,7 +54,7 @@ data class GeneralPreferencesImpl( data class CalculatorPreferencesImpl( override val radianMode: Boolean, - override val separator: Int, + override val formatterSymbols: FormatterSymbols, override val middleZero: Boolean, override val acButton: Boolean, override val partialHistoryView: Boolean, @@ -62,7 +63,7 @@ data class CalculatorPreferencesImpl( ) : CalculatorPreferences data class ConverterPreferencesImpl( - override val separator: Int, + override val formatterSymbols: FormatterSymbols, override val middleZero: Boolean, override val acButton: Boolean, override val precision: Int, @@ -84,7 +85,7 @@ data class DisplayPreferencesImpl( data class FormattingPreferencesImpl( override val digitsPrecision: Int, - override val separator: Int, + override val formatterSymbols: FormatterSymbols, override val outputFormat: Int, ) : FormattingPreferences @@ -93,11 +94,11 @@ data class UnitGroupsPreferencesImpl( ) : UnitGroupsPreferences data class AddSubtractPreferencesImpl( - override val separator: Int, + override val formatterSymbols: FormatterSymbols, ) : AddSubtractPreferences data class BodyMassPreferencesImpl( - override val separator: Int, + override val formatterSymbols: FormatterSymbols, ) : BodyMassPreferences data class AboutPreferencesImpl( diff --git a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PrefsKeys.kt b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PrefsKeys.kt index 0c65ccce..8d38aae7 100644 --- a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PrefsKeys.kt +++ b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PrefsKeys.kt @@ -42,6 +42,8 @@ object PrefsKeys { // FORMATTER val DIGITS_PRECISION = intPreferencesKey("DIGITS_PRECISION_PREF_KEY") val SEPARATOR = intPreferencesKey("SEPARATOR_PREF_KEY") + val FORMATTER_GROUPING = stringPreferencesKey("FORMATTER_GROUPING_PREF_KEY") + val FORMATTER_FRACTIONAL = stringPreferencesKey("FORMATTER_FRACTIONAL_PREF_KEY") val OUTPUT_FORMAT = intPreferencesKey("OUTPUT_FORMAT_PREF_KEY") // CALCULATOR 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/UserPreferencesRepositoryImpl.kt similarity index 94% rename from data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt rename to data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferencesRepositoryImpl.kt index 6d8a97f3..0619eb07 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/UserPreferencesRepositoryImpl.kt @@ -78,7 +78,7 @@ class UserPreferencesRepositoryImpl @Inject constructor( .map { preferences -> CalculatorPreferencesImpl( radianMode = preferences.getRadianMode(), - separator = preferences.getSeparator(), + formatterSymbols = preferences.getFormatterSymbols(), middleZero = preferences.getMiddleZero(), partialHistoryView = preferences.getPartialHistoryView(), precision = preferences.getDigitsPrecision(), @@ -90,7 +90,7 @@ class UserPreferencesRepositoryImpl @Inject constructor( override val converterPrefs: Flow = data .map { preferences -> ConverterPreferencesImpl( - separator = preferences.getSeparator(), + formatterSymbols = preferences.getFormatterSymbols(), middleZero = preferences.getMiddleZero(), precision = preferences.getDigitsPrecision(), outputFormat = preferences.getOutputFormat(), @@ -118,7 +118,7 @@ class UserPreferencesRepositoryImpl @Inject constructor( .map { preferences -> FormattingPreferencesImpl( digitsPrecision = preferences.getDigitsPrecision(), - separator = preferences.getSeparator(), + formatterSymbols = preferences.getFormatterSymbols(), outputFormat = preferences.getOutputFormat(), ) } @@ -133,14 +133,14 @@ class UserPreferencesRepositoryImpl @Inject constructor( override val addSubtractPrefs: Flow = data .map { preferences -> AddSubtractPreferencesImpl( - separator = preferences.getSeparator(), + formatterSymbols = preferences.getFormatterSymbols(), ) } override val bodyMassPrefs: Flow = data .map { preferences -> BodyMassPreferencesImpl( - separator = preferences.getSeparator(), + formatterSymbols = preferences.getFormatterSymbols(), ) } @@ -164,9 +164,13 @@ class UserPreferencesRepositoryImpl @Inject constructor( } } - override suspend fun updateSeparator(separator: Int) { + override suspend fun updateFormatterSymbols(grouping: String, fractional: String) { + // Grouping and fractional symbols are always different + if (grouping == fractional) return + dataStore.edit { preferences -> - preferences[PrefsKeys.SEPARATOR] = separator + preferences[PrefsKeys.FORMATTER_GROUPING] = grouping + preferences[PrefsKeys.FORMATTER_FRACTIONAL] = fractional } } diff --git a/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/BodyMassScreen.kt b/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/BodyMassScreen.kt index 87cc77cc..05af04ee 100644 --- a/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/BodyMassScreen.kt +++ b/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/BodyMassScreen.kt @@ -49,14 +49,15 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.base.R +import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.ui.common.DrawerButton import com.sadellie.unitto.core.ui.common.EmptyScreen import com.sadellie.unitto.core.ui.common.ScaffoldWithTopBar import com.sadellie.unitto.core.ui.common.SegmentedButton import com.sadellie.unitto.core.ui.common.SegmentedButtonsRow import com.sadellie.unitto.core.ui.common.textfield.ExpressionTransformer -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols import com.sadellie.unitto.core.ui.openLink import com.sadellie.unitto.data.common.isEqualTo import com.sadellie.unitto.feature.bodymass.components.BodyMassResult @@ -223,7 +224,7 @@ fun PreviewBodyMassScreen() { weight = TextFieldValue(), normalWeightRange = BigDecimal(30) to BigDecimal(50), result = BigDecimal(18.5), - formatterSymbols = FormatterSymbols.Spaces + formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD) ), updateHeight1 = {}, updateHeight2 = {}, diff --git a/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/BodyMassViewModel.kt b/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/BodyMassViewModel.kt index a0a9e93d..811176f6 100644 --- a/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/BodyMassViewModel.kt +++ b/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/BodyMassViewModel.kt @@ -24,7 +24,6 @@ import android.os.Build import androidx.compose.ui.text.input.TextFieldValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols import com.sadellie.unitto.data.common.combine import com.sadellie.unitto.data.common.stateIn import com.sadellie.unitto.data.model.repository.UserPreferencesRepository @@ -64,7 +63,7 @@ internal class BodyMassViewModel @Inject constructor( weight = weight, result = result, normalWeightRange = normalWeightRange, - formatterSymbols = AllFormatterSymbols.getById(userPrefs.separator) + formatterSymbols = userPrefs.formatterSymbols ) } .mapLatest { ui -> diff --git a/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/UIState.kt b/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/UIState.kt index 997c9339..68c6e880 100644 --- a/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/UIState.kt +++ b/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/UIState.kt @@ -19,7 +19,7 @@ package com.sadellie.unitto.feature.bodymass import androidx.compose.ui.text.input.TextFieldValue -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols +import com.sadellie.unitto.core.base.FormatterSymbols import java.math.BigDecimal internal sealed class UIState { diff --git a/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/components/BodyMassResult.kt b/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/components/BodyMassResult.kt index fbdba599..78d2c28c 100644 --- a/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/components/BodyMassResult.kt +++ b/feature/bodymass/src/main/java/com/sadellie/unitto/feature/bodymass/components/BodyMassResult.kt @@ -37,9 +37,10 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.base.OutputFormat import com.sadellie.unitto.core.base.R -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols +import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.ui.common.textfield.formatExpression import com.sadellie.unitto.data.common.format import java.math.BigDecimal @@ -171,6 +172,6 @@ fun PreviewBodyMassResult() { value = BigDecimal(18.5), range = BigDecimal(50) to BigDecimal(80), rangeSuffix = "kg", - formatterSymbols = FormatterSymbols.Spaces, + formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD), ) } diff --git a/feature/calculator/src/androidTest/java/com/sadellie/unitto/feature/calculator/CalculatorScreenTest.kt b/feature/calculator/src/androidTest/java/com/sadellie/unitto/feature/calculator/CalculatorScreenTest.kt index f1be2ea8..2c942273 100644 --- a/feature/calculator/src/androidTest/java/com/sadellie/unitto/feature/calculator/CalculatorScreenTest.kt +++ b/feature/calculator/src/androidTest/java/com/sadellie/unitto/feature/calculator/CalculatorScreenTest.kt @@ -26,9 +26,10 @@ import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performTouchInput import androidx.compose.ui.test.swipeDown import androidx.compose.ui.text.input.TextFieldValue +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.base.OutputFormat import com.sadellie.unitto.core.base.R -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols +import com.sadellie.unitto.core.base.Token import org.junit.Rule import org.junit.Test @@ -67,7 +68,7 @@ class CalculatorScreenTest { radianMode = false, precision = 3, outputFormat = OutputFormat.PLAIN, - formatterSymbols = FormatterSymbols.Spaces, + formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD), history = emptyList(), middleZero = false, acButton = true, @@ -100,7 +101,7 @@ class CalculatorScreenTest { radianMode = false, precision = 3, outputFormat = OutputFormat.PLAIN, - formatterSymbols = FormatterSymbols.Spaces, + formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD), history = emptyList(), middleZero = false, acButton = true, diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt index a298bf95..bcf5a105 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt @@ -62,14 +62,15 @@ import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.sadellie.unitto.core.base.FormatterSymbols 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.LocalWindowSize import com.sadellie.unitto.core.ui.WindowHeightSizeClass import com.sadellie.unitto.core.ui.common.DrawerButton import com.sadellie.unitto.core.ui.common.EmptyScreen import com.sadellie.unitto.core.ui.common.ScaffoldWithTopBar -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols import com.sadellie.unitto.data.model.HistoryItem import com.sadellie.unitto.feature.calculator.components.CalculatorKeyboard import com.sadellie.unitto.feature.calculator.components.HistoryItemHeight @@ -355,7 +356,7 @@ private fun PreviewCalculatorScreen() { radianMode = false, precision = 3, outputFormat = OutputFormat.PLAIN, - formatterSymbols = FormatterSymbols.Spaces, + formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD), history = historyItems, middleZero = false, acButton = true, diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorUIState.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorUIState.kt index baa5b4c6..670221b5 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorUIState.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorUIState.kt @@ -20,8 +20,8 @@ package com.sadellie.unitto.feature.calculator import androidx.annotation.StringRes import androidx.compose.ui.text.input.TextFieldValue +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.base.R -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols import com.sadellie.unitto.data.model.HistoryItem internal sealed class CalculatorUIState { 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 1a70fbcc..c3672bab 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 @@ -24,7 +24,6 @@ import androidx.lifecycle.SavedStateHandle 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.addBracket import com.sadellie.unitto.core.ui.common.textfield.addTokens import com.sadellie.unitto.core.ui.common.textfield.deleteTokens @@ -79,7 +78,7 @@ internal class CalculatorViewModel @Inject constructor( radianMode = prefs.radianMode, precision = prefs.precision, outputFormat = prefs.outputFormat, - formatterSymbols = AllFormatterSymbols.getById(prefs.separator), + formatterSymbols = prefs.formatterSymbols, history = history, middleZero = prefs.middleZero, acButton = prefs.acButton, diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/CalculatorKeyboard.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/CalculatorKeyboard.kt index be3ca4d7..4882c3c2 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/CalculatorKeyboard.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/CalculatorKeyboard.kt @@ -110,7 +110,6 @@ import com.sadellie.unitto.core.ui.common.icons.iconpack.RightBracket import com.sadellie.unitto.core.ui.common.icons.iconpack.Root import com.sadellie.unitto.core.ui.common.icons.iconpack.Sin import com.sadellie.unitto.core.ui.common.icons.iconpack.Tan -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols @Composable internal fun CalculatorKeyboard( @@ -182,8 +181,8 @@ private fun PortraitKeyboard( val angleIcon = remember(radianMode) { if (radianMode) IconPack.Rad else IconPack.Deg } val angleIconDescription = remember(radianMode) { if (radianMode) R.string.keyboard_radian else R.string.keyboard_degree } - val fractionalIcon = remember(fractional) { if (fractional == Token.Digit.dot) IconPack.Dot else IconPack.Comma } - val fractionalIconDescription = remember(fractional) { if (fractional == Token.Digit.dot) R.string.keyboard_dot else R.string.comma } + val fractionalIcon = remember(fractional) { if (fractional == Token.PERIOD) IconPack.Dot else IconPack.Comma } + val fractionalIconDescription = remember(fractional) { if (fractional == Token.PERIOD) R.string.keyboard_dot else R.string.comma } var showAdditional: Boolean by remember { mutableStateOf(false) } val expandRotation: Float by animateFloatAsState( @@ -414,8 +413,8 @@ private fun LandscapeKeyboard( val angleIcon = remember(radianMode) { if (radianMode) IconPack.Rad else IconPack.Deg } val angleIconDescription = remember(radianMode) { if (radianMode) R.string.keyboard_radian else R.string.keyboard_degree } - val fractionalIcon = remember(fractional) { if (fractional == Token.Digit.dot) IconPack.Dot else IconPack.Comma } - val fractionalIconDescription = remember(fractional) { if (fractional == Token.Digit.dot) R.string.keyboard_dot else R.string.comma } + val fractionalIcon = remember(fractional) { if (fractional == Token.PERIOD) IconPack.Dot else IconPack.Comma } + val fractionalIconDescription = remember(fractional) { if (fractional == Token.PERIOD) R.string.keyboard_dot else R.string.comma } Crossfade( targetState = invMode, @@ -544,7 +543,7 @@ private fun PreviewPortraitKeyboard() { PortraitKeyboard( modifier = Modifier.fillMaxHeight(), radianMode = true, - fractional = FormatterSymbols.Comma.fractional, + fractional = Token.PERIOD, addSymbol = {}, clearSymbols = {}, deleteSymbol = {}, @@ -564,7 +563,7 @@ private fun PreviewLandscapeKeyboard() { LandscapeKeyboard( modifier = Modifier.fillMaxHeight(), radianMode = true, - fractional = FormatterSymbols.Comma.fractional, + fractional = Token.PERIOD, addSymbol = {}, clearSymbols = {}, deleteSymbol = {}, diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/HistoryList.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/HistoryList.kt index 7ba3c09b..39ced770 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/HistoryList.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/HistoryList.kt @@ -47,9 +47,10 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.base.R +import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.ui.common.textfield.FixedExpressionInputTextField -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols import com.sadellie.unitto.data.model.HistoryItem import java.text.SimpleDateFormat import java.util.Locale @@ -225,7 +226,7 @@ private fun PreviewHistoryList() { .background(MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f)) .fillMaxSize(), historyItems = historyItems, - formatterSymbols = FormatterSymbols.Spaces, + formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD), addTokens = {}, onDelete = {}, showDeleteButtons = true, diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/TextBox.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/TextBox.kt index e1daaf1a..20f630bf 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/TextBox.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/components/TextBox.kt @@ -39,10 +39,10 @@ import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTag import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.ui.LocalWindowSize import com.sadellie.unitto.core.ui.WindowHeightSizeClass 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.SimpleTextField import com.sadellie.unitto.feature.calculator.CalculationResult 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 b57f6660..cbe8a40e 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 @@ -70,6 +70,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.base.OutputFormat import com.sadellie.unitto.core.base.R import com.sadellie.unitto.core.base.Token @@ -80,7 +81,6 @@ import com.sadellie.unitto.core.ui.common.EmptyScreen import com.sadellie.unitto.core.ui.common.PortraitLandscape import com.sadellie.unitto.core.ui.common.ScaffoldWithTopBar 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.NumberBaseTextField import com.sadellie.unitto.core.ui.common.textfield.SimpleTextField import com.sadellie.unitto.core.ui.datetime.formatDateWeekDayMonthYear @@ -425,7 +425,7 @@ private fun ConverterResultTextField( result: ConverterResult, scale: Int = 0, outputFormat: Int = OutputFormat.PLAIN, - formatterSymbols: FormatterSymbols = FormatterSymbols.Spaces, + formatterSymbols: FormatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD), onErrorClick: () -> Unit = {}, ) { val mContext = LocalContext.current 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 47fc4eb4..40e64429 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 @@ -20,9 +20,9 @@ package com.sadellie.unitto.feature.converter import android.content.Context import androidx.compose.ui.text.input.TextFieldValue +import com.sadellie.unitto.core.base.FormatterSymbols 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.core.ui.common.textfield.formatExpression import com.sadellie.unitto.data.common.format import com.sadellie.unitto.data.common.isEqualTo 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 f5ea3f4e..c3c9a804 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 @@ -23,7 +23,6 @@ import androidx.lifecycle.SavedStateHandle 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.addBracket import com.sadellie.unitto.core.ui.common.textfield.addTokens import com.sadellie.unitto.core.ui.common.textfield.deleteTokens @@ -94,7 +93,7 @@ internal class ConverterViewModel @Inject constructor( unitFrom = unitFrom as DefaultUnit, unitTo = unitTo as DefaultUnit, middleZero = prefs.middleZero, - formatterSymbols = AllFormatterSymbols.getById(prefs.separator), + formatterSymbols = prefs.formatterSymbols, scale = prefs.precision, outputFormat = prefs.outputFormat, formatTime = prefs.unitConverterFormatTime, diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/UnitSelectorUIState.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/UnitSelectorUIState.kt index 03d6bcec..5bb17a78 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/UnitSelectorUIState.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/UnitSelectorUIState.kt @@ -19,7 +19,7 @@ package com.sadellie.unitto.feature.converter import androidx.compose.ui.text.input.TextFieldValue -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.data.model.UnitGroup import com.sadellie.unitto.data.model.UnitsListSorting import com.sadellie.unitto.data.model.unit.AbstractUnit diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/UnitSelectorViewModel.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/UnitSelectorViewModel.kt index e35672ac..55833ef5 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/UnitSelectorViewModel.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/UnitSelectorViewModel.kt @@ -22,7 +22,6 @@ import androidx.compose.ui.text.input.TextFieldValue import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols import com.sadellie.unitto.data.common.stateIn import com.sadellie.unitto.data.model.UnitGroup import com.sadellie.unitto.data.model.repository.UnitsRepository @@ -112,7 +111,7 @@ internal class UnitSelectorViewModel @Inject constructor( sorting = prefs.unitConverterSorting, scale = prefs.precision, outputFormat = prefs.outputFormat, - formatterSymbols = AllFormatterSymbols.getById(prefs.separator), + formatterSymbols = prefs.formatterSymbols, ) } .mapLatest { ui -> diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/UnitToSelectorScreen.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/UnitToSelectorScreen.kt index ae918bf6..b423e98b 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/UnitToSelectorScreen.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/UnitToSelectorScreen.kt @@ -28,11 +28,12 @@ import androidx.compose.ui.platform.LocalContext 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.FormatterSymbols 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.EmptyScreen import com.sadellie.unitto.core.ui.common.SearchBar -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols import com.sadellie.unitto.core.ui.common.textfield.formatExpression import com.sadellie.unitto.data.common.format import com.sadellie.unitto.data.converter.UnitID @@ -189,7 +190,7 @@ private fun UnitToSelectorPreview() { input = "100", scale = 3, outputFormat = OutputFormat.PLAIN, - formatterSymbols = FormatterSymbols.Spaces, + formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD), ), onQueryChange = {}, toggleFavoritesOnly = {}, 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 f1b0f51d..e54714e7 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 @@ -66,7 +66,6 @@ import com.sadellie.unitto.core.ui.common.icons.iconpack.Plus import com.sadellie.unitto.core.ui.common.icons.iconpack.Power import com.sadellie.unitto.core.ui.common.icons.iconpack.RightBracket import com.sadellie.unitto.core.ui.common.icons.iconpack.Root -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols @Composable internal fun DefaultKeyboard( @@ -79,8 +78,8 @@ internal fun DefaultKeyboard( acButton: Boolean, addBracket: () -> Unit, ) { - val fractionalIcon = remember(fractional) { if (fractional == Token.Digit.dot) IconPack.Dot else IconPack.Comma } - val fractionalIconDescription = remember(fractional) { if (fractional == Token.Digit.dot) R.string.keyboard_dot else R.string.comma } + val fractionalIcon = remember(fractional) { if (fractional == Token.PERIOD) IconPack.Dot else IconPack.Comma } + val fractionalIconDescription = remember(fractional) { if (fractional == Token.PERIOD) R.string.keyboard_dot else R.string.comma } val contentHeight: Float = if (LocalWindowSize.current.heightSizeClass < WindowHeightSizeClass.Medium) KeyboardButtonContentHeightShort else KeyboardButtonContentHeightTall KeypadFlow( @@ -178,7 +177,7 @@ private fun PreviewConverterKeyboard() { addDigit = {}, clearInput = {}, deleteDigit = {}, - fractional = FormatterSymbols.Spaces.fractional, + fractional = Token.PERIOD, middleZero = false, acButton = true, addBracket = {} 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 index b1632226..d87d15ef 100644 --- 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 @@ -19,7 +19,8 @@ package com.sadellie.unitto.feature.converter import android.content.Context -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols +import com.sadellie.unitto.core.base.FormatterSymbols +import com.sadellie.unitto.core.base.Token import org.junit.Assert import org.junit.Test import org.junit.runner.RunWith @@ -32,7 +33,7 @@ class ConverterUIStateKtTest { @Test fun format() { - val formatterSymbols = FormatterSymbols.Spaces + val formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD) var basicValue = BigDecimal("1") val mContext: Context = RuntimeEnvironment.getApplication().applicationContext diff --git a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/addsubtract/AddSubtractUIState.kt b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/addsubtract/AddSubtractUIState.kt index dfa33347..4dd24005 100644 --- a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/addsubtract/AddSubtractUIState.kt +++ b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/addsubtract/AddSubtractUIState.kt @@ -19,7 +19,8 @@ package com.sadellie.unitto.feature.datecalculator.addsubtract import androidx.compose.ui.text.input.TextFieldValue -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols +import com.sadellie.unitto.core.base.FormatterSymbols +import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.feature.datecalculator.ZonedDateTimeUtils import java.time.ZonedDateTime @@ -32,6 +33,6 @@ internal data class AddSubtractState( val hours: TextFieldValue = TextFieldValue(), val minutes: TextFieldValue = TextFieldValue(), val addition: Boolean = true, - val formatterSymbols: FormatterSymbols = FormatterSymbols.Spaces, + val formatterSymbols: FormatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD), val allowVibration: Boolean = false, ) diff --git a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/addsubtract/AddSubtractViewModel.kt b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/addsubtract/AddSubtractViewModel.kt index 2e2d8703..478c238e 100644 --- a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/addsubtract/AddSubtractViewModel.kt +++ b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/addsubtract/AddSubtractViewModel.kt @@ -22,7 +22,6 @@ 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.ui.common.textfield.AllFormatterSymbols import com.sadellie.unitto.data.model.repository.UserPreferencesRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers @@ -46,7 +45,7 @@ internal class AddSubtractViewModel @Inject constructor( val uiState: StateFlow = _uiState .combine(userPreferencesRepository.addSubtractPrefs) { uiState, userPrefs -> return@combine uiState.copy( - formatterSymbols = AllFormatterSymbols.getById(userPrefs.separator), + formatterSymbols = userPrefs.formatterSymbols, ) } .onEach { updateResult() } diff --git a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DateDifferencePage.kt b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DateDifferencePage.kt index 0d89011d..61c85ce6 100644 --- a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DateDifferencePage.kt +++ b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DateDifferencePage.kt @@ -40,9 +40,10 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.base.OutputFormat import com.sadellie.unitto.core.base.R -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols +import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.ui.common.textfield.formatExpression import com.sadellie.unitto.data.common.format import com.sadellie.unitto.feature.datecalculator.ZonedDateTimeUtils @@ -185,7 +186,7 @@ fun DateDifferenceViewPreview() { ), precision = 3, outputFormat = OutputFormat.PLAIN, - formatterSymbols = FormatterSymbols.Spaces + formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD) ), setStartDate = {}, setEndDate = {}, diff --git a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DateDifferenceViewModel.kt b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DateDifferenceViewModel.kt index f0ef5e91..35e50f74 100644 --- a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DateDifferenceViewModel.kt +++ b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DateDifferenceViewModel.kt @@ -20,7 +20,6 @@ package com.sadellie.unitto.feature.datecalculator.difference import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols import com.sadellie.unitto.data.common.stateIn import com.sadellie.unitto.data.model.repository.UserPreferencesRepository import com.sadellie.unitto.feature.datecalculator.ZonedDateTimeUtils @@ -55,7 +54,7 @@ internal class DateDifferenceViewModel @Inject constructor( result = result, precision = prefs.digitsPrecision, outputFormat = prefs.outputFormat, - formatterSymbols = AllFormatterSymbols.getById(prefs.separator) + formatterSymbols = prefs.formatterSymbols ) } .mapLatest { ui -> diff --git a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DifferenceUIState.kt b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DifferenceUIState.kt index ef43dbab..673a0de6 100644 --- a/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DifferenceUIState.kt +++ b/feature/datecalculator/src/main/java/com/sadellie/unitto/feature/datecalculator/difference/DifferenceUIState.kt @@ -18,7 +18,7 @@ package com.sadellie.unitto.feature.datecalculator.difference -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols +import com.sadellie.unitto.core.base.FormatterSymbols import java.time.ZonedDateTime internal sealed class DifferenceUIState { diff --git a/feature/glance/src/main/java/com/sadellie/unitto/feature/glance/glance/CalculatorWidget.kt b/feature/glance/src/main/java/com/sadellie/unitto/feature/glance/glance/CalculatorWidget.kt index a73df471..bdc214b2 100644 --- a/feature/glance/src/main/java/com/sadellie/unitto/feature/glance/glance/CalculatorWidget.kt +++ b/feature/glance/src/main/java/com/sadellie/unitto/feature/glance/glance/CalculatorWidget.kt @@ -54,9 +54,8 @@ import androidx.glance.text.Text import androidx.glance.text.TextAlign import androidx.glance.text.TextStyle import androidx.glance.unit.ColorProvider +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.base.Token -import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols import com.sadellie.unitto.core.ui.common.textfield.formatExpression import com.sadellie.unitto.data.model.repository.UserPreferencesRepository import com.sadellie.unitto.data.model.userprefs.CalculatorPreferences @@ -139,7 +138,7 @@ private fun ReadyUI( val input = glancePrefs[CalculatorWidget.inputPrefKey] ?: "" val output = glancePrefs[CalculatorWidget.outputPrefKey] ?: "" val equalClicked = glancePrefs[CalculatorWidget.equalClickedPrefKey] ?: false - val formatterSymbols = AllFormatterSymbols.getById(appPrefs.separator) + val formatterSymbols = appPrefs.formatterSymbols fun runCalculateAction( input: String, diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/calculator/CalculatorSettingsScreen.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/calculator/CalculatorSettingsScreen.kt index 480edaaa..0a684734 100644 --- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/calculator/CalculatorSettingsScreen.kt +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/calculator/CalculatorSettingsScreen.kt @@ -28,9 +28,10 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.base.OutputFormat import com.sadellie.unitto.core.base.R -import com.sadellie.unitto.core.base.Separator +import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.ui.common.EmptyScreen import com.sadellie.unitto.core.ui.common.ListItem import com.sadellie.unitto.core.ui.common.NavigateUpButton @@ -83,7 +84,7 @@ private fun PreviewCalculatorSettingsScreenStandard() { CalculatorSettingsScreen( prefs = CalculatorPreferencesImpl( radianMode = true, - separator = Separator.SPACE, + formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD), middleZero = false, acButton = false, partialHistoryView = false, diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/converter/ConverterSettingsScreen.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/converter/ConverterSettingsScreen.kt index 7d462f30..553325b3 100644 --- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/converter/ConverterSettingsScreen.kt +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/converter/ConverterSettingsScreen.kt @@ -34,9 +34,10 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.base.OutputFormat import com.sadellie.unitto.core.base.R -import com.sadellie.unitto.core.base.Separator +import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.ui.common.EmptyScreen import com.sadellie.unitto.core.ui.common.ListItem import com.sadellie.unitto.core.ui.common.NavigateUpButton @@ -133,7 +134,7 @@ private fun ConverterSettingsScreen( private fun PreviewConverterSettingsScreen() { ConverterSettingsScreen( prefs = ConverterPreferencesImpl( - separator = Separator.SPACE, + formatterSymbols = FormatterSymbols(Token.SPACE, Token.PERIOD), middleZero = false, precision = 3, outputFormat = OutputFormat.PLAIN, diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/formatting/FormattingScreen.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/formatting/FormattingScreen.kt index 724d728a..c84e6912 100644 --- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/formatting/FormattingScreen.kt +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/formatting/FormattingScreen.kt @@ -18,13 +18,18 @@ package com.sadellie.unitto.feature.settings.formatting +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.expandVertically +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentWidth -import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.rememberScrollState import androidx.compose.material.icons.Icons @@ -38,6 +43,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier @@ -48,10 +54,11 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.sadellie.unitto.core.base.FormatterSymbols import com.sadellie.unitto.core.base.MAX_PRECISION import com.sadellie.unitto.core.base.OutputFormat import com.sadellie.unitto.core.base.R -import com.sadellie.unitto.core.base.Separator +import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.ui.common.EmptyScreen import com.sadellie.unitto.core.ui.common.ListItem import com.sadellie.unitto.core.ui.common.NavigateUpButton @@ -60,7 +67,6 @@ import com.sadellie.unitto.core.ui.common.ScaffoldWithLargeTopBar import com.sadellie.unitto.core.ui.common.SegmentedButton import com.sadellie.unitto.core.ui.common.SegmentedButtonsRow import com.sadellie.unitto.core.ui.common.Slider -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols import com.sadellie.unitto.core.ui.common.textfield.formatExpression import com.sadellie.unitto.core.ui.theme.LocalNumberTypography import com.sadellie.unitto.data.common.format @@ -79,7 +85,7 @@ fun FormattingRoute( navigateUpAction = navigateUpAction, uiState = uiState, onPrecisionChange = viewModel::updatePrecision, - onSeparatorChange = viewModel::updateSeparator, + updateFormatterSymbols = viewModel::updateFormatterSymbols, onOutputFormatChange = viewModel::updateOutputFormat, ) } @@ -91,7 +97,7 @@ fun FormattingScreen( navigateUpAction: () -> Unit, uiState: FormattingUIState, onPrecisionChange: (Int) -> Unit, - onSeparatorChange: (Int) -> Unit, + updateFormatterSymbols: (grouping: String, fractional: String) -> Unit, onOutputFormatChange: (Int) -> Unit, precisions: ClosedFloatingPointRange = 0f..16f, // 16th is a MAX_PRECISION (1000) ) { @@ -114,143 +120,162 @@ fun FormattingScreen( title = stringResource(R.string.settings_formatting), navigationIcon = { NavigateUpButton(navigateUpAction) }, ) { paddingValues -> - LazyColumn( + Column( modifier = Modifier .padding(paddingValues) ) { - item("preview") { - PagedIsland( + PagedIsland( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + pagerState = rememberPagerState { 2 }, + ) { currentPage -> + val preview = when (currentPage) { + 0 -> "123456.${"789123456".repeat(ceil(uiState.precision.toDouble() / 9.0).toInt())}" + 1 -> "0.${"1".padStart(uiState.precision, '0')}" + else -> "" + } + .toBigDecimalOrNull() + ?.format(uiState.precision, uiState.outputFormat) + ?.formatExpression(uiState.formatterSymbols) + ?: "" + + Text( + text = preview, + style = LocalNumberTypography.current.displayMedium, + maxLines = 1, modifier = Modifier .fillMaxWidth() - .padding(16.dp), - pagerState = rememberPagerState { 2 }, - ) { currentPage -> - val preview = when (currentPage) { - 0 -> "123456.${"789123456".repeat(ceil(uiState.precision.toDouble() / 9.0).toInt())}" - 1 -> "0.${"1".padStart(uiState.precision, '0')}" - else -> "" - } - .toBigDecimalOrNull() - ?.format(uiState.precision, uiState.outputFormat) - ?.formatExpression(uiState.formatterSymbols) - ?: "" + .horizontalScroll(rememberScrollState()), + textAlign = TextAlign.End, + color = MaterialTheme.colorScheme.onSecondaryContainer + ) + } - Text( - text = preview, - style = LocalNumberTypography.current.displayMedium, - maxLines = 1, - modifier = Modifier - .fillMaxWidth() - .horizontalScroll(rememberScrollState()), - textAlign = TextAlign.End, - color = MaterialTheme.colorScheme.onSecondaryContainer + ListItem( + leadingContent = { + Icon( + Icons.Default.Architecture, + stringResource(R.string.settings_precision) + ) + }, + headlineContent = { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier.fillMaxWidth() + ) { + Text(stringResource(R.string.settings_precision)) + Text(precisionText) + } + }, + supportingContent = { + Text(stringResource(R.string.settings_precision_support)) + } + ) + + Slider( + modifier = Modifier.padding(start = 56.dp, end = 16.dp), + value = uiState.precision.toFloat(), + valueRange = precisions, + onValueChange = { onPrecisionChange(it.roundToInt()) }, + ) + + ListItem( + leadingContent = { + Icon(Icons.Default._123, stringResource(R.string.settings_thousands_separator)) + }, + headlineContent = { Text(stringResource(R.string.settings_thousands_separator)) }, + ) + + Row( + Modifier + .horizontalScroll(rememberScrollState()) + .wrapContentWidth() + .padding(start = 56.dp) + ) { + SegmentedButtonsRow { + SegmentedButton( + label = stringResource(R.string.settings_space), + onClick = { updateFormatterSymbols(Token.SPACE, uiState.formatterSymbols.fractional) }, + selected = uiState.formatterSymbols.grouping == Token.SPACE + ) + SegmentedButton( + label = stringResource(R.string.settings_period), + onClick = { updateFormatterSymbols(Token.PERIOD, Token.COMMA) }, + selected = uiState.formatterSymbols.grouping == Token.PERIOD, + ) + SegmentedButton( + label = stringResource(R.string.comma), + onClick = { updateFormatterSymbols(Token.COMMA, Token.PERIOD) }, + selected = uiState.formatterSymbols.grouping == Token.COMMA, ) } } - item("precision_label") { - ListItem( - leadingContent = { - Icon( - Icons.Default.Architecture, - stringResource(R.string.settings_precision) - ) - }, - headlineContent = { - Row( - horizontalArrangement = Arrangement.SpaceBetween, - modifier = Modifier.fillMaxWidth() - ) { - Text(stringResource(R.string.settings_precision)) - Text(precisionText) - } - }, - supportingContent = { - Text(stringResource(R.string.settings_precision_support)) - } - ) - } - - item("precision_slider") { - Slider( - modifier = Modifier.padding(start = 56.dp, end = 16.dp), - value = uiState.precision.toFloat(), - valueRange = precisions, - onValueChange = { onPrecisionChange(it.roundToInt()) }, - ) - } - - item("separator_label") { - ListItem( - leadingContent = { - Icon(Icons.Default._123, stringResource(R.string.settings_separator)) - }, - headlineContent = { Text(stringResource(R.string.settings_separator)) }, - supportingContent = { Text(stringResource(R.string.settings_separator_support)) }, - ) - } - - item("separator") { - Row( - Modifier - .horizontalScroll(rememberScrollState()) - .wrapContentWidth() - .padding(start = 56.dp) + AnimatedVisibility( + visible = uiState.formatterSymbols.grouping == Token.SPACE, + enter = expandVertically() + fadeIn(), + exit = shrinkVertically() + fadeOut() + ) { + Column( + modifier = Modifier.padding(start = 40.dp) ) { - SegmentedButtonsRow { - SegmentedButton( - label = stringResource(R.string.settings_space), - onClick = { onSeparatorChange(Separator.SPACE) }, - selected = Separator.SPACE == uiState.separator - ) - SegmentedButton( - label = stringResource(R.string.settings_period), - onClick = { onSeparatorChange(Separator.PERIOD) }, - selected = Separator.PERIOD == uiState.separator - ) - SegmentedButton( - label = stringResource(R.string.comma), - onClick = { onSeparatorChange(Separator.COMMA) }, - selected = Separator.COMMA == uiState.separator - ) + ListItem( + modifier = Modifier, + headlineContent = { Text(stringResource(R.string.settings_decimal_separator)) }, + ) + Row( + Modifier + .horizontalScroll(rememberScrollState()) + .wrapContentWidth() + .padding(start = 16.dp) + ) { + SegmentedButtonsRow { + SegmentedButton( + label = stringResource(R.string.settings_period), + onClick = { updateFormatterSymbols(Token.SPACE, Token.PERIOD) }, + selected = uiState.formatterSymbols.fractional == Token.PERIOD, + ) + SegmentedButton( + label = stringResource(R.string.comma), + onClick = { updateFormatterSymbols(Token.SPACE, Token.COMMA) }, + selected = uiState.formatterSymbols.fractional == Token.COMMA, + ) + } } } } - item("output_format_label") { - ListItem( - leadingContent = { - Icon(Icons.Default.EMobiledata, stringResource(R.string.settings_precision)) - }, - headlineContent = { Text(stringResource(R.string.settings_exponential_notation)) }, - supportingContent = { Text(stringResource(R.string.settings_exponential_notation_support)) } - ) - } + ListItem( + leadingContent = { + Icon(Icons.Default.EMobiledata, stringResource(R.string.settings_precision)) + }, + headlineContent = { Text(stringResource(R.string.settings_exponential_notation)) }, + supportingContent = { Text(stringResource(R.string.settings_exponential_notation_support)) } + ) - item("output_format") { - Row( - Modifier - .horizontalScroll(rememberScrollState()) - .wrapContentWidth() - .padding(start = 56.dp) - ) { - SegmentedButtonsRow { - SegmentedButton( - label = stringResource(R.string.settings_auto), - onClick = { onOutputFormatChange(OutputFormat.ALLOW_ENGINEERING) }, - selected = OutputFormat.ALLOW_ENGINEERING == uiState.outputFormat - ) - SegmentedButton( - label = stringResource(R.string.enabled_label), - onClick = { onOutputFormatChange(OutputFormat.FORCE_ENGINEERING) }, - selected = OutputFormat.FORCE_ENGINEERING == uiState.outputFormat - ) - SegmentedButton( - label = stringResource(R.string.disabled_label), - onClick = { onOutputFormatChange(OutputFormat.PLAIN) }, - selected = OutputFormat.PLAIN == uiState.outputFormat - ) - } + Row( + Modifier + .horizontalScroll(rememberScrollState()) + .wrapContentWidth() + .padding(start = 56.dp) + ) { + SegmentedButtonsRow { + SegmentedButton( + label = stringResource(R.string.settings_auto), + onClick = { onOutputFormatChange(OutputFormat.ALLOW_ENGINEERING) }, + selected = OutputFormat.ALLOW_ENGINEERING == uiState.outputFormat + ) + SegmentedButton( + label = stringResource(R.string.enabled_label), + onClick = { onOutputFormatChange(OutputFormat.FORCE_ENGINEERING) }, + selected = OutputFormat.FORCE_ENGINEERING == uiState.outputFormat + ) + SegmentedButton( + label = stringResource(R.string.disabled_label), + onClick = { onOutputFormatChange(OutputFormat.PLAIN) }, + selected = OutputFormat.PLAIN == uiState.outputFormat + ) } } } @@ -261,18 +286,19 @@ fun FormattingScreen( @Composable private fun PreviewFormattingScreen() { var currentPrecision by remember { mutableIntStateOf(6) } - var currentSeparator by remember { mutableIntStateOf(Separator.COMMA) } + var currentFormatterSymbols by remember { mutableStateOf(FormatterSymbols(Token.SPACE, Token.PERIOD)) } var currentOutputFormat by remember { mutableIntStateOf(OutputFormat.PLAIN) } FormattingScreen( uiState = FormattingUIState( precision = 16, - separator = Separator.SPACE, outputFormat = OutputFormat.PLAIN, - formatterSymbols = FormatterSymbols.Spaces + formatterSymbols = currentFormatterSymbols ), onPrecisionChange = { currentPrecision = it }, - onSeparatorChange = { currentSeparator = it }, + updateFormatterSymbols = updateFormatterSymbols@{ grouping, fractional -> + currentFormatterSymbols = FormatterSymbols(grouping, fractional) + }, onOutputFormatChange = { currentOutputFormat = it }, navigateUpAction = {}, ) diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/formatting/FormattingUIState.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/formatting/FormattingUIState.kt index 65d1f826..89a41b3b 100644 --- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/formatting/FormattingUIState.kt +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/formatting/FormattingUIState.kt @@ -18,11 +18,10 @@ package com.sadellie.unitto.feature.settings.formatting -import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols +import com.sadellie.unitto.core.base.FormatterSymbols data class FormattingUIState( val precision: Int, - val separator: Int, val outputFormat: Int, val formatterSymbols: FormatterSymbols, ) 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 64741259..44062399 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 @@ -21,7 +21,6 @@ package com.sadellie.unitto.feature.settings.formatting import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.sadellie.unitto.core.base.MAX_PRECISION -import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols import com.sadellie.unitto.data.common.stateIn import com.sadellie.unitto.data.model.repository.UserPreferencesRepository import dagger.hilt.android.lifecycle.HiltViewModel @@ -38,9 +37,8 @@ class FormattingViewModel @Inject constructor( val uiState = _prefs.map { mainPrefs -> FormattingUIState( precision = mainPrefs.digitsPrecision, - separator = mainPrefs.separator, outputFormat = mainPrefs.outputFormat, - formatterSymbols = AllFormatterSymbols.getById(mainPrefs.separator) + formatterSymbols = mainPrefs.formatterSymbols ) } .stateIn(viewModelScope, null) @@ -55,10 +53,10 @@ class FormattingViewModel @Inject constructor( } /** - * @see UserPreferencesRepository.updateSeparator + * @see UserPreferencesRepository.updateFormatterSymbols */ - fun updateSeparator(separator: Int) = viewModelScope.launch { - userPreferencesRepository.updateSeparator(separator) + fun updateFormatterSymbols(grouping: String, fractional: String) = viewModelScope.launch { + userPreferencesRepository.updateFormatterSymbols(grouping, fractional) } /**