Refactor formatter

This commit is contained in:
Sad Ellie 2023-02-28 21:37:02 +04:00
parent 8d98cbfddf
commit 7150fc9133
7 changed files with 215 additions and 159 deletions

View File

@ -115,8 +115,7 @@ object Token {
multiply, multiplyDisplay, multiply, multiplyDisplay,
plus, minus, minusDisplay, divide, divideDisplay, plus, minus, minusDisplay, divide, divideDisplay,
baseA, baseB, baseC, baseD, baseE, baseF, baseA, baseB, baseC, baseD, baseE, baseF,
_1, _2, _3, _4, _5, _6, _7, _8, _9, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _0
dot
).sortedByDescending { it.length } ).sortedByDescending { it.length }
} }
} }

View File

@ -18,10 +18,9 @@
package com.sadellie.unitto.core.ui package com.sadellie.unitto.core.ui
import androidx.compose.runtime.Composable import android.content.Context
import androidx.compose.ui.res.stringResource
import com.sadellie.unitto.core.base.Token
import com.sadellie.unitto.core.base.Separator import com.sadellie.unitto.core.base.Separator
import com.sadellie.unitto.core.base.Token
import java.math.BigDecimal import java.math.BigDecimal
import java.math.RoundingMode import java.math.RoundingMode
@ -90,8 +89,6 @@ open class UnittoFormatter {
if (input.contains(Token.E)) return input.replace(Token.dot, fractional) if (input.contains(Token.E)) return input.replace(Token.dot, fractional)
var output = input var output = input
// We may receive expressions. Find all numbers in this expression
val allNumbers: List<String> = input.getOnlyNumbers() val allNumbers: List<String> = input.getOnlyNumbers()
allNumbers.forEach { allNumbers.forEach {
@ -116,7 +113,11 @@ open class UnittoFormatter {
// Remove grouping // Remove grouping
// 12345,6789 // 12345,6789
// Replace fractional with "." because formatter accepts only numbers where fractional is a dot // Replace fractional with "." because formatter accepts only numbers where fractional is a dot
return format(removeFormat(input)) return format(
input
.replace(grouping, "")
.replace(fractional, Token.dot)
)
} }
/** /**
@ -129,17 +130,67 @@ open class UnittoFormatter {
Separator.COMMA -> COMMA Separator.COMMA -> COMMA
else -> SPACE else -> SPACE
} }
.also { if (it == grouping) return input }
val sFractional = if (separator == Separator.PERIOD) Token.comma else Token.dot val sFractional = if (separator == Separator.PERIOD) Token.comma else Token.dot
return input return input
.replace(sGrouping, grouping) .replace(sGrouping, "\t")
.replace(sFractional, fractional) .replace(sFractional, fractional)
.replace("\t", grouping)
} }
fun removeFormat(input: String): String { fun toSeparator(input: String, separator: Int): String {
return input val output = filterUnknownSymbols(input).replace(fractional, Token.dot)
.replace(grouping, "") val sGrouping = when (separator) {
.replace(fractional, Token.dot) Separator.PERIOD -> PERIOD
Separator.COMMA -> COMMA
else -> SPACE
}
val sFractional = if (separator == Separator.PERIOD) Token.comma else Token.dot
return format(output)
.replace(grouping, "\t")
.replace(fractional, sFractional)
.replace("\t", sGrouping)
}
fun removeGrouping(input: String): String = input.replace(grouping, "")
/**
* Takes [input] and [basicUnit] of the unit to format it to be more human readable.
*
* @return String like "1d 12h 12s".
*/
fun formatTime(context: Context, input: String, basicUnit: BigDecimal?): String {
if (basicUnit == null) return Token._0
try {
// Don't need magic if the input is zero
if (BigDecimal(input).compareTo(BigDecimal.ZERO) == 0) return Token._0
} catch (e: NumberFormatException) {
// For case such as "10-" and "("
return Token._0
}
// Attoseconds don't need "magic"
if (basicUnit.compareTo(BigDecimal.ONE) == 0) return formatNumber(input)
var result = if (input.startsWith(Token.minus)) Token.minus else ""
var remainingSeconds = BigDecimal(input)
.abs()
.multiply(basicUnit)
.setScale(0, RoundingMode.HALF_EVEN)
if (remainingSeconds.compareTo(BigDecimal.ZERO) == 0) return Token._0
timeDivisions.forEach { (timeStr, divider) ->
val division = remainingSeconds.divideAndRemainder(divider)
val time = division.component1()
remainingSeconds = division.component2()
if (time.compareTo(BigDecimal.ZERO) == 1) {
result += "${formatNumber(time.toPlainString())}${context.getString(timeStr)} "
}
}
return result.trimEnd()
} }
/** /**
@ -170,47 +221,31 @@ open class UnittoFormatter {
return (output + remainingPart.replace(".", fractional)) return (output + remainingPart.replace(".", fractional))
} }
/**
* Takes [input] and [basicUnit] of the unit to format it to be more human readable.
*
* @return String like "1d 12h 12s".
*/
@Composable
fun formatTime(input: String, basicUnit: BigDecimal?): String {
if (basicUnit == null) return Token._0
try {
// Don't need magic if the input is zero
if (BigDecimal(input).compareTo(BigDecimal.ZERO) == 0) return Token._0
} catch (e: NumberFormatException) {
// For case such as "10-" and "("
return Token._0
}
// Attoseconds don't need "magic"
if (basicUnit.compareTo(BigDecimal.ONE) == 0) return formatNumber(input)
var result = if (input.startsWith(Token.minus)) Token.minus else ""
var remainingSeconds = BigDecimal(input)
.abs()
.multiply(basicUnit)
.setScale(0, RoundingMode.HALF_EVEN)
if (remainingSeconds.compareTo(BigDecimal.ZERO) == 0) return Token._0
timeDivisions.forEach { (timeStr, divider) ->
val division = remainingSeconds.divideAndRemainder(divider)
val time = division.component1()
remainingSeconds = division.component2()
if (time.compareTo(BigDecimal.ZERO) == 1) {
result += "${formatNumber(time.toPlainString())}${stringResource(timeStr)} "
}
}
return result.trimEnd()
}
/** /**
* @receiver Must be a string with a dot (".") used as a fractional. * @receiver Must be a string with a dot (".") used as a fractional.
*/ */
private fun String.getOnlyNumbers(): List<String> = private fun String.getOnlyNumbers(): List<String> =
numbersRegex.findAll(this).map(MatchResult::value).toList() numbersRegex.findAll(this).map(MatchResult::value).toList()
fun filterUnknownSymbols(input: String): String {
var clearStr = input.replace(" ", "")
var garbage = clearStr
// String with unknown symbols
Token.knownSymbols.plus(fractional).forEach {
garbage = garbage.replace(it, " ")
}
// Remove unknown symbols from input
garbage.split(" ").forEach {
clearStr = clearStr.replace(it, "")
}
clearStr = clearStr
.replace(Token.divide, Token.divideDisplay)
.replace(Token.multiply, Token.multiplyDisplay)
.replace(Token.minus, Token.minusDisplay)
return clearStr
}
} }

View File

@ -18,6 +18,7 @@
package com.sadellie.unitto.core.ui package com.sadellie.unitto.core.ui
import android.content.Context
import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.junit4.createComposeRule
import com.sadellie.unitto.core.base.Separator import com.sadellie.unitto.core.base.Separator
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
@ -25,6 +26,7 @@ import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import java.math.BigDecimal import java.math.BigDecimal
private val formatter = Formatter private val formatter = Formatter
@ -93,98 +95,121 @@ class FormatterTest {
@Test @Test
fun formatTimeTest() { fun formatTimeTest() {
formatter.setSeparator(Separator.SPACES) formatter.setSeparator(Separator.SPACES)
composeTestRule.setContent {
var basicValue = BigDecimal.valueOf(1) var basicValue = BigDecimal.valueOf(1)
assertEquals("-28", formatter.formatTime("-28", basicValue)) val mContext: Context = RuntimeEnvironment.getApplication().applicationContext
assertEquals("-0.05", formatter.formatTime("-0.05", basicValue)) assertEquals("-28", formatter.formatTime(mContext, "-28", basicValue))
assertEquals("0", formatter.formatTime("0", basicValue)) assertEquals("-0.05", formatter.formatTime(mContext, "-0.05", basicValue))
assertEquals("0", formatter.formatTime("-0", basicValue)) assertEquals("0", formatter.formatTime(mContext, "0", basicValue))
assertEquals("0", formatter.formatTime(mContext, "-0", basicValue))
basicValue = BigDecimal.valueOf(86_400_000_000_000_000_000_000.0) basicValue = BigDecimal.valueOf(86_400_000_000_000_000_000_000.0)
assertEquals("-28d", formatter.formatTime("-28", basicValue)) assertEquals("-28d", formatter.formatTime(mContext, "-28", basicValue))
assertEquals("-1h 12m", formatter.formatTime("-0.05", basicValue)) assertEquals("-1h 12m", formatter.formatTime(mContext, "-0.05", basicValue))
assertEquals("0", formatter.formatTime("0", basicValue)) assertEquals("0", formatter.formatTime(mContext, "0", basicValue))
assertEquals("0", formatter.formatTime("-0", basicValue)) assertEquals("0", formatter.formatTime(mContext, "-0", basicValue))
// DAYS // DAYS
basicValue = BigDecimal.valueOf(86_400_000_000_000_000_000_000.0) basicValue = BigDecimal.valueOf(86_400_000_000_000_000_000_000.0)
assertEquals("12h", formatter.formatTime("0.5", basicValue)) assertEquals("12h", formatter.formatTime(mContext, "0.5", basicValue))
assertEquals("1h 12m", formatter.formatTime("0.05", basicValue)) assertEquals("1h 12m", formatter.formatTime(mContext, "0.05", basicValue))
assertEquals("7m 12s", formatter.formatTime("0.005", basicValue)) assertEquals("7m 12s", formatter.formatTime(mContext, "0.005", basicValue))
assertEquals("28d", formatter.formatTime("28", basicValue)) assertEquals("28d", formatter.formatTime(mContext, "28", basicValue))
assertEquals("90d", formatter.formatTime("90", basicValue)) assertEquals("90d", formatter.formatTime(mContext, "90", basicValue))
assertEquals("90d 12h", formatter.formatTime("90.5", basicValue)) assertEquals("90d 12h", formatter.formatTime(mContext, "90.5", basicValue))
assertEquals("90d 7m 12s", formatter.formatTime("90.005", basicValue)) assertEquals("90d 7m 12s", formatter.formatTime(mContext, "90.005", basicValue))
// HOURS // HOURS
basicValue = BigDecimal.valueOf(3_600_000_000_000_000_000_000.0) basicValue = BigDecimal.valueOf(3_600_000_000_000_000_000_000.0)
assertEquals("30m", formatter.formatTime("0.5", basicValue)) assertEquals("30m", formatter.formatTime(mContext, "0.5", basicValue))
assertEquals("3m", formatter.formatTime("0.05", basicValue)) assertEquals("3m", formatter.formatTime(mContext, "0.05", basicValue))
assertEquals("18s", formatter.formatTime("0.005", basicValue)) assertEquals("18s", formatter.formatTime(mContext, "0.005", basicValue))
assertEquals("1d 4h", formatter.formatTime("28", basicValue)) assertEquals("1d 4h", formatter.formatTime(mContext, "28", basicValue))
assertEquals("3d 18h", formatter.formatTime("90", basicValue)) assertEquals("3d 18h", formatter.formatTime(mContext, "90", basicValue))
assertEquals("3d 18h 30m", formatter.formatTime("90.5", basicValue)) assertEquals("3d 18h 30m", formatter.formatTime(mContext, "90.5", basicValue))
assertEquals("3d 18h 18s", formatter.formatTime("90.005", basicValue)) assertEquals("3d 18h 18s", formatter.formatTime(mContext, "90.005", basicValue))
// MINUTES // MINUTES
basicValue = BigDecimal.valueOf(60_000_000_000_000_000_000.0) basicValue = BigDecimal.valueOf(60_000_000_000_000_000_000.0)
assertEquals("30s", formatter.formatTime("0.5", basicValue)) assertEquals("30s", formatter.formatTime(mContext, "0.5", basicValue))
assertEquals("3s", formatter.formatTime("0.05", basicValue)) assertEquals("3s", formatter.formatTime(mContext, "0.05", basicValue))
assertEquals("300ms", formatter.formatTime("0.005", basicValue)) assertEquals("300ms", formatter.formatTime(mContext, "0.005", basicValue))
assertEquals("28m", formatter.formatTime("28", basicValue)) assertEquals("28m", formatter.formatTime(mContext, "28", basicValue))
assertEquals("1h 30m", formatter.formatTime("90", basicValue)) assertEquals("1h 30m", formatter.formatTime(mContext, "90", basicValue))
assertEquals("1h 30m 30s", formatter.formatTime("90.5", basicValue)) assertEquals("1h 30m 30s", formatter.formatTime(mContext, "90.5", basicValue))
assertEquals("1h 30m 300ms", formatter.formatTime("90.005", basicValue)) assertEquals("1h 30m 300ms", formatter.formatTime(mContext, "90.005", basicValue))
// SECONDS // SECONDS
basicValue = BigDecimal.valueOf(1_000_000_000_000_000_000) basicValue = BigDecimal.valueOf(1_000_000_000_000_000_000)
assertEquals("500ms", formatter.formatTime("0.5", basicValue)) assertEquals("500ms", formatter.formatTime(mContext, "0.5", basicValue))
assertEquals("50ms", formatter.formatTime("0.05", basicValue)) assertEquals("50ms", formatter.formatTime(mContext, "0.05", basicValue))
assertEquals("5ms", formatter.formatTime("0.005", basicValue)) assertEquals("5ms", formatter.formatTime(mContext, "0.005", basicValue))
assertEquals("28s", formatter.formatTime("28", basicValue)) assertEquals("28s", formatter.formatTime(mContext, "28", basicValue))
assertEquals("1m 30s", formatter.formatTime("90", basicValue)) assertEquals("1m 30s", formatter.formatTime(mContext, "90", basicValue))
assertEquals("1m 30s 500ms", formatter.formatTime("90.5", basicValue)) assertEquals("1m 30s 500ms", formatter.formatTime(mContext, "90.5", basicValue))
assertEquals("1m 30s 5ms", formatter.formatTime("90.005", basicValue)) assertEquals("1m 30s 5ms", formatter.formatTime(mContext, "90.005", basicValue))
// MILLISECONDS // MILLISECONDS
basicValue = BigDecimal.valueOf(1_000_000_000_000_000) basicValue = BigDecimal.valueOf(1_000_000_000_000_000)
assertEquals("500µs", formatter.formatTime("0.5", basicValue)) assertEquals("500µs", formatter.formatTime(mContext, "0.5", basicValue))
assertEquals("50µs", formatter.formatTime("0.05", basicValue)) assertEquals("50µs", formatter.formatTime(mContext, "0.05", basicValue))
assertEquals("5µs", formatter.formatTime("0.005", basicValue)) assertEquals("5µs", formatter.formatTime(mContext, "0.005", basicValue))
assertEquals("28ms", formatter.formatTime("28", basicValue)) assertEquals("28ms", formatter.formatTime(mContext, "28", basicValue))
assertEquals("90ms", formatter.formatTime("90", basicValue)) assertEquals("90ms", formatter.formatTime(mContext, "90", basicValue))
assertEquals("90ms 500µs", formatter.formatTime("90.5", basicValue)) assertEquals("90ms 500µs", formatter.formatTime(mContext, "90.5", basicValue))
assertEquals("90ms 5µs", formatter.formatTime("90.005", basicValue)) assertEquals("90ms 5µs", formatter.formatTime(mContext, "90.005", basicValue))
// MICROSECONDS // MICROSECONDS
basicValue = BigDecimal.valueOf(1_000_000_000_000) basicValue = BigDecimal.valueOf(1_000_000_000_000)
assertEquals("500ns", formatter.formatTime("0.5", basicValue)) assertEquals("500ns", formatter.formatTime(mContext, "0.5", basicValue))
assertEquals("50ns", formatter.formatTime("0.05", basicValue)) assertEquals("50ns", formatter.formatTime(mContext, "0.05", basicValue))
assertEquals("5ns", formatter.formatTime("0.005", basicValue)) assertEquals("5ns", formatter.formatTime(mContext, "0.005", basicValue))
assertEquals("28µs", formatter.formatTime("28", basicValue)) assertEquals("28µs", formatter.formatTime(mContext, "28", basicValue))
assertEquals("90µs", formatter.formatTime("90", basicValue)) assertEquals("90µs", formatter.formatTime(mContext, "90", basicValue))
assertEquals("90µs 500ns", formatter.formatTime("90.5", basicValue)) assertEquals("90µs 500ns", formatter.formatTime(mContext, "90.5", basicValue))
assertEquals("90µs 5ns", formatter.formatTime("90.005", basicValue)) assertEquals("90µs 5ns", formatter.formatTime(mContext, "90.005", basicValue))
// NANOSECONDS // NANOSECONDS
basicValue = BigDecimal.valueOf(1_000_000_000) basicValue = BigDecimal.valueOf(1_000_000_000)
assertEquals("500 000 000as", formatter.formatTime("0.5", basicValue)) assertEquals("500 000 000as", formatter.formatTime(mContext, "0.5", basicValue))
assertEquals("50 000 000as", formatter.formatTime("0.05", basicValue)) assertEquals("50 000 000as", formatter.formatTime(mContext, "0.05", basicValue))
assertEquals("5 000 000as", formatter.formatTime("0.005", basicValue)) assertEquals("5 000 000as", formatter.formatTime(mContext, "0.005", basicValue))
assertEquals("28ns", formatter.formatTime("28", basicValue)) assertEquals("28ns", formatter.formatTime(mContext, "28", basicValue))
assertEquals("90ns", formatter.formatTime("90", basicValue)) assertEquals("90ns", formatter.formatTime(mContext, "90", basicValue))
assertEquals("90ns 500 000 000as", formatter.formatTime("90.5", basicValue)) assertEquals("90ns 500 000 000as", formatter.formatTime(mContext, "90.5", basicValue))
assertEquals("90ns 5 000 000as", formatter.formatTime("90.005", basicValue)) assertEquals("90ns 5 000 000as", formatter.formatTime(mContext, "90.005", basicValue))
// ATTOSECONDS // ATTOSECONDS
basicValue = BigDecimal.valueOf(1) basicValue = BigDecimal.valueOf(1)
assertEquals("0.5", formatter.formatTime("0.5", basicValue)) assertEquals("0.5", formatter.formatTime(mContext, "0.5", basicValue))
assertEquals("0.05", formatter.formatTime("0.05", basicValue)) assertEquals("0.05", formatter.formatTime(mContext, "0.05", basicValue))
assertEquals("0.005", formatter.formatTime("0.005", basicValue)) assertEquals("0.005", formatter.formatTime(mContext, "0.005", basicValue))
assertEquals("28", formatter.formatTime("28", basicValue)) assertEquals("28", formatter.formatTime(mContext, "28", basicValue))
assertEquals("90", formatter.formatTime("90", basicValue)) assertEquals("90", formatter.formatTime(mContext, "90", basicValue))
assertEquals("90.5", formatter.formatTime("90.5", basicValue)) assertEquals("90.5", formatter.formatTime(mContext, "90.5", basicValue))
assertEquals("90.005", formatter.formatTime("90.005", basicValue)) assertEquals("90.005", formatter.formatTime(mContext, "90.005", basicValue))
} }
@Test
fun fromSeparatorToSpacesTest() {
formatter.setSeparator(Separator.SPACES)
assertEquals("123 456.789", formatter.fromSeparator("123,456.789", Separator.COMMA))
assertEquals("123 456.789", formatter.fromSeparator("123 456.789", Separator.SPACES))
assertEquals("123 456.789", formatter.fromSeparator("123.456,789", Separator.PERIOD))
}
@Test
fun fromSeparatorToPeriodTest() {
formatter.setSeparator(Separator.PERIOD)
assertEquals("123.456,789", formatter.fromSeparator("123,456.789", Separator.COMMA))
assertEquals("123.456,789", formatter.fromSeparator("123 456.789", Separator.SPACES))
assertEquals("123.456,789", formatter.fromSeparator("123.456,789", Separator.PERIOD))
}
@Test
fun fromSeparatorToCommaTest() {
formatter.setSeparator(Separator.COMMA)
assertEquals("123,456.789", formatter.fromSeparator("123,456.789", Separator.COMMA))
assertEquals("123,456.789", formatter.fromSeparator("123 456.789", Separator.SPACES))
assertEquals("123,456.789", formatter.fromSeparator("123.456,789", Separator.PERIOD))
} }
} }

View File

@ -100,7 +100,9 @@ internal fun CalculatorRoute(
// This method is called immediately after copying formatted text, we replace it with the // This method is called immediately after copying formatted text, we replace it with the
// the unformatted version. // the unformatted version.
clipboardManager.setText( clipboardManager.setText(
AnnotatedString(Formatter.removeFormat(clipboardText.text)) AnnotatedString(
clipboardText.text.replace(Formatter.grouping, "")
)
) )
} }

View File

@ -128,27 +128,7 @@ class TextFieldController @Inject constructor() {
private fun String.fixFormat(): String = localFormatter.reFormat(this) private fun String.fixFormat(): String = localFormatter.reFormat(this)
private fun String.filterUnknownSymbols(): String { private fun String.filterUnknownSymbols() = localFormatter.filterUnknownSymbols(this)
var clearStr = this.replace(" ", "")
var garbage = clearStr
// String with unknown symbols
Token.knownSymbols.forEach {
garbage = garbage.replace(it, " ")
}
// Remove unknown symbols from input
garbage.split(" ").forEach {
clearStr = clearStr.replace(it, "")
}
clearStr = clearStr
.replace(Token.divide, Token.divideDisplay)
.replace(Token.multiply, Token.multiplyDisplay)
.replace(Token.minus, Token.minusDisplay)
return clearStr
}
inner class CursorFixer { inner class CursorFixer {
private val illegalTokens by lazy { private val illegalTokens by lazy {

View File

@ -31,6 +31,7 @@ import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalTextInputService import androidx.compose.ui.platform.LocalTextInputService
import androidx.compose.ui.platform.LocalTextToolbar import androidx.compose.ui.platform.LocalTextToolbar
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import com.sadellie.unitto.core.base.Separator import com.sadellie.unitto.core.base.Separator
@ -46,6 +47,7 @@ internal fun InputTextField(
cutCallback: () -> Unit cutCallback: () -> Unit
) { ) {
val clipboardManager = LocalClipboardManager.current val clipboardManager = LocalClipboardManager.current
val formattedInput: TextFieldValue by remember(value) { val formattedInput: TextFieldValue by remember(value) {
derivedStateOf { derivedStateOf {
value.copy( value.copy(
@ -57,7 +59,11 @@ internal fun InputTextField(
} }
fun copyToClipboard() = clipboardManager.setText( fun copyToClipboard() = clipboardManager.setText(
formattedInput.annotatedString.subSequence(formattedInput.selection) AnnotatedString(
Formatter.removeGrouping(
formattedInput.annotatedString.subSequence(formattedInput.selection).text
)
)
) )
CompositionLocalProvider( CompositionLocalProvider(
@ -65,7 +71,13 @@ internal fun InputTextField(
LocalTextToolbar provides UnittoTextToolbar( LocalTextToolbar provides UnittoTextToolbar(
view = LocalView.current, view = LocalView.current,
copyCallback = ::copyToClipboard, copyCallback = ::copyToClipboard,
pasteCallback = { pasteCallback(clipboardManager.getText()?.text ?: "") }, pasteCallback = {
pasteCallback(
Formatter.toSeparator(
clipboardManager.getText()?.text ?: "", Separator.COMMA
)
)
},
cutCallback = { copyToClipboard(); cutCallback() } cutCallback = { copyToClipboard(); cutCallback() }
) )
) { ) {

View File

@ -38,6 +38,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate import androidx.compose.ui.draw.rotate
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.sadellie.unitto.core.ui.Formatter import com.sadellie.unitto.core.ui.Formatter
@ -88,6 +89,7 @@ internal fun TopScreenPart(
targetValue = if (swapped) 0f else 180f, targetValue = if (swapped) 0f else 180f,
animationSpec = tween(easing = FastOutSlowInEasing) animationSpec = tween(easing = FastOutSlowInEasing)
) )
val mContext = LocalContext.current
Column( Column(
modifier = modifier, modifier = modifier,
@ -115,6 +117,7 @@ internal fun TopScreenPart(
converterMode == ConverterMode.BASE -> outputValue.uppercase() converterMode == ConverterMode.BASE -> outputValue.uppercase()
formatTime and (unitTo?.group == UnitGroup.TIME) -> { formatTime and (unitTo?.group == UnitGroup.TIME) -> {
Formatter.formatTime( Formatter.formatTime(
context = mContext,
input = calculatedValue ?: inputValue, input = calculatedValue ?: inputValue,
basicUnit = unitFrom?.basicUnit basicUnit = unitFrom?.basicUnit
) )