mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-18 16:25:27 +02:00
parent
224ddd8bad
commit
263a1139dc
@ -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,
|
||||
)
|
@ -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"
|
||||
|
@ -245,6 +245,7 @@ Alternatively you can use "Export" -->
|
||||
<string name="settings_currency_rates_note_text">Currency rates are updated daily. There\'s no real-time market monitoring in the app</string>
|
||||
<string name="settings_currency_rates_note_title">Wrong currency rates?</string>
|
||||
<string name="settings_dark_mode">Dark</string>
|
||||
<string name="settings_decimal_separator">Decimal separator</string>
|
||||
<string name="settings_disable_unit_group_description">Disable unit group</string>
|
||||
<string name="settings_display">Display</string>
|
||||
<string name="settings_display_support">App look and feel</string>
|
||||
@ -301,6 +302,7 @@ Maybe this can be labeled better? Let me know. It should be something that can d
|
||||
<string name="settings_system_font_support">Use system font for texts in app</string>
|
||||
<string name="settings_terms_and_conditions">Terms and Conditions</string>
|
||||
<string name="settings_third_party_licenses">Third party licenses</string>
|
||||
<string name="settings_thousands_separator">Thousands separator</string>
|
||||
<string name="settings_title">Settings</string>
|
||||
<string name="settings_translate_app">Translate this app</string>
|
||||
<string name="settings_translate_app_support">Join POEditor project to help</string>
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.]+") }
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 }
|
||||
}
|
||||
}
|
@ -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
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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())
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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<ConverterPreferences> = 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<AddSubtractPreferences> = data
|
||||
.map { preferences ->
|
||||
AddSubtractPreferencesImpl(
|
||||
separator = preferences.getSeparator(),
|
||||
formatterSymbols = preferences.getFormatterSymbols(),
|
||||
)
|
||||
}
|
||||
|
||||
override val bodyMassPrefs: Flow<BodyMassPreferences> = 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
|
||||
}
|
||||
}
|
||||
|
@ -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 = {},
|
||||
|
@ -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 ->
|
||||
|
@ -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 {
|
||||
|
@ -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),
|
||||
)
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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 = {},
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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 ->
|
||||
|
@ -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 = {},
|
||||
|
@ -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 = {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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<AddSubtractState> = _uiState
|
||||
.combine(userPreferencesRepository.addSubtractPrefs) { uiState, userPrefs ->
|
||||
return@combine uiState.copy(
|
||||
formatterSymbols = AllFormatterSymbols.getById(userPrefs.separator),
|
||||
formatterSymbols = userPrefs.formatterSymbols,
|
||||
)
|
||||
}
|
||||
.onEach { updateResult() }
|
||||
|
@ -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 = {},
|
||||
|
@ -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 ->
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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<Float> = 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 = {},
|
||||
)
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user