From 12938e9122feeb6094860fb22f93c974c1e8571a Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Thu, 11 Jul 2024 21:38:30 +0200 Subject: [PATCH 01/27] chore: Update dependencies Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- gradle/libs.versions.toml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 42a81fa5..9c5cc044 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,25 +5,25 @@ versionName = "NumberHub" androidxBrowserBrowser = "1.8.0" androidGradlePlugin = "8.3.2" androidxActivityActivityCompose = "1.9.0" -androidxAppCompatAppCompat = "1.6.1" -androidxCompose = "1.6.7" +androidxAppCompatAppCompat = "1.7.0" +androidxCompose = "1.6.8" androidxComposeCompiler = "1.5.9" androidxComposeMaterial3 = "1.2.1" androidxCoreCoreKts = "1.13.1" -androidxGlanceGlance = "1.0.0" +androidxGlanceGlance = "1.1.0" androidxDatastoreDatastorePreferences = "1.1.1" -androidxEspresso = "3.5.1" +androidxEspresso = "3.6.1" androidxHiltHiltNavigationCompose = "1.2.0" androidxMacroBenchmark = "1.2.4" -androidxLifecycleLifecycleRuntimeCompose = "2.7.0" +androidxLifecycleLifecycleRuntimeCompose = "2.8.3" androidxNavigationNavigationCompose = "2.7.7" androidxProfileinstallerProfileinstaller = "1.3.1" androidxRoom = "2.6.1" -androidxTest = "1.5.0" -androidxTestExtJunitKtx = "1.1.5" -androidxTestRunner = "1.5.2" +androidxTest = "1.6.1" +androidxTestExtJunitKtx = "1.2.1" +androidxTestRunner = "1.6.1" androidxUiAutomator = "2.3.0" -androidxWindowWindow = "1.2.0" +androidxWindowWindow = "1.3.0" androidxWorkWorkRuntimeKtx = "2.9.0" comAndroidToolsDesugarJdkLibs = "2.0.4" comGithubSadellieThemmo = "1.3.0" From 7e9d057535e594edbc3af1c0b2ed0079bbd7410a Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Fri, 12 Jul 2024 22:43:39 +0200 Subject: [PATCH 02/27] fix: Do not remember width and height to update correctly Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../java/app/myzel394/numberhub/core/ui/common/KeypadFlow.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/ui/src/main/java/app/myzel394/numberhub/core/ui/common/KeypadFlow.kt b/core/ui/src/main/java/app/myzel394/numberhub/core/ui/common/KeypadFlow.kt index 8f749381..fa28aa9e 100644 --- a/core/ui/src/main/java/app/myzel394/numberhub/core/ui/common/KeypadFlow.kt +++ b/core/ui/src/main/java/app/myzel394/numberhub/core/ui/common/KeypadFlow.kt @@ -25,7 +25,6 @@ import androidx.compose.foundation.layout.FlowRowScope import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier /** @@ -51,8 +50,8 @@ fun KeypadFlow( @IntRange(0, 100) verticalPadding: Int = 10, content: @Composable FlowRowScope.(width: Float, height: Float) -> Unit, ) { - val height: Float = remember { (1f - verticalPadding / 100f) / rows } - val width: Float = remember { (1f - horizontalPadding / 100f) / columns } + val height: Float = (1f - verticalPadding / 100f) / rows + val width: Float = (1f - horizontalPadding / 100f) / columns FlowRow( modifier = modifier, From 084d66ac881b4d66c01caa35d839787f24d022c7 Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Fri, 12 Jul 2024 22:44:37 +0200 Subject: [PATCH 03/27] feat: Add custom keyboard depending on input unit when in base converter screen Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../feature/converter/ConverterScreen.kt | 1 + .../converter/components/ConverterKeyboard.kt | 239 ++++++++++++++++-- 2 files changed, 214 insertions(+), 26 deletions(-) diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt index c6be06a3..4039d8cb 100644 --- a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt @@ -250,6 +250,7 @@ private fun NumberBase( addDigit = { updateInput1(uiState.input.addTokens(it)) }, deleteDigit = { updateInput1(uiState.input.deleteTokens()) }, clearInput = { updateInput1(TextFieldValue()) }, + basis = uiState.unitFrom, ) }, ) diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt index 3a1ab001..29cff357 100644 --- a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt @@ -18,18 +18,24 @@ package app.myzel394.numberhub.feature.converter.components +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import app.myzel394.numberhub.core.base.R import app.myzel394.numberhub.core.base.Token import app.myzel394.numberhub.core.ui.LocalWindowSize import app.myzel394.numberhub.core.ui.WindowHeightSizeClass +import app.myzel394.numberhub.core.ui.common.ColumnWithConstraints import app.myzel394.numberhub.core.ui.common.KeyboardButtonFilled import app.myzel394.numberhub.core.ui.common.KeyboardButtonLight import app.myzel394.numberhub.core.ui.common.KeyboardButtonTertiary @@ -65,6 +71,8 @@ import app.myzel394.numberhub.core.ui.common.icons.iconpack.Plus import app.myzel394.numberhub.core.ui.common.icons.iconpack.Power import app.myzel394.numberhub.core.ui.common.icons.iconpack.RightBracket import app.myzel394.numberhub.core.ui.common.icons.iconpack.Root +import app.myzel394.numberhub.data.model.converter.unit.BasicUnit +import kotlin.math.ceil @Composable internal fun DefaultKeyboard( @@ -86,7 +94,9 @@ internal fun DefaultKeyboard( rows = 5, columns = 4, ) { width, height -> - val bModifier = Modifier.fillMaxWidth(width).fillMaxHeight(height) + val bModifier = Modifier + .fillMaxWidth(width) + .fillMaxHeight(height) if (acButton) { KeyboardButtonTertiary(bModifier, IconPack.Clear, stringResource(R.string.delete_label), contentHeight) { clearInput() } @@ -125,46 +135,200 @@ internal fun DefaultKeyboard( } } +val AVAILABLE_NUMBERS = mapOf( + Token.Digit._0 to IconPack.Key0, + Token.Digit._1 to IconPack.Key1, + Token.Digit._2 to IconPack.Key2, + Token.Digit._3 to IconPack.Key3, + Token.Digit._4 to IconPack.Key4, + Token.Digit._5 to IconPack.Key5, + Token.Digit._6 to IconPack.Key6, + Token.Digit._7 to IconPack.Key7, + Token.Digit._8 to IconPack.Key8, + Token.Digit._9 to IconPack.Key9, + Token.Letter._A to IconPack.KeyA, + Token.Letter._B to IconPack.KeyB, + Token.Letter._C to IconPack.KeyC, + Token.Letter._D to IconPack.KeyD, + Token.Letter._E to IconPack.KeyE, + Token.Letter._F to IconPack.KeyF, +) + @Composable internal fun NumberBaseKeyboard( modifier: Modifier, addDigit: (String) -> Unit, clearInput: () -> Unit, deleteDigit: () -> Unit, + basis: BasicUnit.NumberBase, ) { val contentHeight: Float = if (LocalWindowSize.current.heightSizeClass < WindowHeightSizeClass.Medium) KeyboardButtonToken.CONTENT_HEIGHT_SHORT else KeyboardButtonToken.CONTENT_HEIGHT_TALL + val amount = basis.factor.toInt() - KeypadFlow( - modifier = modifier, - rows = 6, - columns = 3, - ) { width, height -> - val bModifier = Modifier.fillMaxWidth(width).fillMaxHeight(height) - val wideButtonModifier = Modifier.fillMaxHeight(height).fillMaxWidth(width * 2) + val columns: Int = when { + amount == 5 -> 2 + amount == 3 -> 2 + amount == 7 -> 2 + amount == 10 -> 3 + amount < 10 -> if (amount.and(1) == 0) 2 else if (amount % 3 == 0) 3 else amount % 3 + else -> 3 + } + val rows = when { + amount == 5 -> 3 + amount == 3 -> 2 + amount == 7 -> 4 + amount == 10 -> 4 + amount < 10 -> ceil(amount.toDouble() / columns.toDouble()).toInt() + 1 + amount == 11 -> 5 + amount == 12 -> 5 + amount == 13 -> 5 + else -> 6 + } - KeyboardButtonFilled(bModifier, IconPack.KeyA, Token.Letter._A, contentHeight) { addDigit(Token.Letter._A) } - KeyboardButtonFilled(bModifier, IconPack.KeyB, Token.Letter._B, contentHeight) { addDigit(Token.Letter._B) } - KeyboardButtonFilled(bModifier, IconPack.KeyC, Token.Letter._C, contentHeight) { addDigit(Token.Letter._C) } + ColumnWithConstraints(Modifier) { constraints -> + val horizontalSpacing = 8.dp + val verticalSpacing = 12.dp + val height: Float = (1f - (verticalSpacing * (rows - 1) / constraints.maxHeight)) / rows - KeyboardButtonFilled(bModifier, IconPack.KeyD, Token.Letter._D, contentHeight) { addDigit(Token.Letter._D) } - KeyboardButtonFilled(bModifier, IconPack.KeyE, Token.Letter._E, contentHeight) { addDigit(Token.Letter._E) } - KeyboardButtonFilled(bModifier, IconPack.KeyF, Token.Letter._F, contentHeight) { addDigit(Token.Letter._F) } + FlowRow( + modifier = modifier, + maxItemsInEachRow = columns, + horizontalArrangement = Arrangement.spacedBy(horizontalSpacing), + verticalArrangement = Arrangement.spacedBy(verticalSpacing), + ) { + val bModifier = Modifier + .fillMaxHeight(height) + .fillMaxWidth() - KeyboardButtonLight(bModifier, IconPack.Key7, Token.Digit._7, contentHeight) { addDigit(Token.Digit._7) } - KeyboardButtonLight(bModifier, IconPack.Key8, Token.Digit._8, contentHeight) { addDigit(Token.Digit._8) } - KeyboardButtonLight(bModifier, IconPack.Key9, Token.Digit._9, contentHeight) { addDigit(Token.Digit._9) } + when { + amount in arrayOf(3, 5, 7) -> { + for (int in createSortedArray(1.. { + for (int in createSortedArray(0.. { + for (int in createSortedArray(1..9, columns)) { + val key = AVAILABLE_NUMBERS.keys.elementAt(int) + val icon = AVAILABLE_NUMBERS[key]!! + KeyboardButtonLight( + bModifier.weight(1f), + icon, + key, + contentHeight, + ) { addDigit(key) } + } + + KeyboardButtonLight( + bModifier.weight(1f), + IconPack.Key0, + Token.Digit._0, + contentHeight, + ) { addDigit(Token.Digit._0) } + KeyboardButtonTertiary( + bModifier.weight(2f), + IconPack.Backspace, + stringResource(R.string.delete_label), + contentHeight, + clearInput, + ) { deleteDigit() } + } + + else -> { + val lettersAmount = (10.. { + val result = mutableListOf() + val rows = ceil(range.count().toDouble() / columns.toDouble()).toInt() + for (row in rows downTo 0) { + for (column in 0 until columns) { + val index = row * columns + column + range.first + if (index <= range.last) { + result.add(index) + } + } + } + + return result +} From 1a2ae455c93142a2eae5ef77cda0cd89353ce1e7 Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Fri, 12 Jul 2024 22:46:28 +0200 Subject: [PATCH 04/27] fix: Add Hexadecimal as default NumberBase Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../numberhub/data/model/converter/unit/BasicUnit.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/data/model/src/main/java/app/myzel394/numberhub/data/model/converter/unit/BasicUnit.kt b/data/model/src/main/java/app/myzel394/numberhub/data/model/converter/unit/BasicUnit.kt index 1b697d5f..14298017 100644 --- a/data/model/src/main/java/app/myzel394/numberhub/data/model/converter/unit/BasicUnit.kt +++ b/data/model/src/main/java/app/myzel394/numberhub/data/model/converter/unit/BasicUnit.kt @@ -37,6 +37,16 @@ sealed interface BasicUnit { interface NumberBase : BasicUnit { fun convert(unitTo: NumberBase, value: String): String + + companion object { + val Hexadecimal = NumberBaseUnit( + "hexadecimal", + BigDecimal(16), + UnitGroup.NUMBER_BASE, + 0, + 0, + ) + } } interface Default : BasicUnit { From 792dc9366b887c0a4f39c27309484c041abe5d17 Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Fri, 12 Jul 2024 23:08:48 +0200 Subject: [PATCH 05/27] feat: Set default ordering to scale ascending Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../java/app/myzel394/numberhub/data/userprefs/PreferenceExt.kt | 2 +- .../numberhub/feature/converter/UnitFromSelectorScreen.kt | 2 +- .../numberhub/feature/converter/UnitToSelectorScreen.kt | 2 +- .../feature/settings/converter/ConverterSettingsScreen.kt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/userprefs/src/main/java/app/myzel394/numberhub/data/userprefs/PreferenceExt.kt b/data/userprefs/src/main/java/app/myzel394/numberhub/data/userprefs/PreferenceExt.kt index 8fc3e046..f353ddb9 100644 --- a/data/userprefs/src/main/java/app/myzel394/numberhub/data/userprefs/PreferenceExt.kt +++ b/data/userprefs/src/main/java/app/myzel394/numberhub/data/userprefs/PreferenceExt.kt @@ -120,7 +120,7 @@ internal fun Preferences.getUnitConverterFormatTime(): Boolean { internal fun Preferences.getUnitConverterSorting(): UnitsListSorting { return this[PrefsKeys.UNIT_CONVERTER_SORTING] - ?.let { UnitsListSorting.valueOf(it) } ?: UnitsListSorting.USAGE + ?.let { UnitsListSorting.valueOf(it) } ?: UnitsListSorting.SCALE_ASC } internal fun Preferences.getShownUnitGroups(): List { diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/UnitFromSelectorScreen.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/UnitFromSelectorScreen.kt index 90be2e13..e2990f6d 100644 --- a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/UnitFromSelectorScreen.kt +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/UnitFromSelectorScreen.kt @@ -156,7 +156,7 @@ private fun UnitFromSelectorScreenPreview() { selectedUnitGroup = UnitGroup.SPEED, shownUnitGroups = UnitGroup.entries, showFavoritesOnly = false, - sorting = UnitsListSorting.USAGE, + sorting = UnitsListSorting.SCALE_ASC, ), onQueryChange = {}, toggleFavoritesOnly = {}, diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/UnitToSelectorScreen.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/UnitToSelectorScreen.kt index 1acfcba4..8ed18192 100644 --- a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/UnitToSelectorScreen.kt +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/UnitToSelectorScreen.kt @@ -155,7 +155,7 @@ private fun UnitToSelectorPreview() { query = TextFieldValue("test"), units = units, showFavoritesOnly = false, - sorting = UnitsListSorting.USAGE, + sorting = UnitsListSorting.SCALE_ASC, input = "100", scale = 3, outputFormat = OutputFormat.PLAIN, diff --git a/feature/settings/src/main/java/app/myzel394/numberhub/feature/settings/converter/ConverterSettingsScreen.kt b/feature/settings/src/main/java/app/myzel394/numberhub/feature/settings/converter/ConverterSettingsScreen.kt index 2b82e9d6..38085237 100644 --- a/feature/settings/src/main/java/app/myzel394/numberhub/feature/settings/converter/ConverterSettingsScreen.kt +++ b/feature/settings/src/main/java/app/myzel394/numberhub/feature/settings/converter/ConverterSettingsScreen.kt @@ -139,7 +139,7 @@ private fun PreviewConverterSettingsScreen() { precision = 3, outputFormat = OutputFormat.PLAIN, unitConverterFormatTime = false, - unitConverterSorting = UnitsListSorting.USAGE, + unitConverterSorting = UnitsListSorting.SCALE_ASC, shownUnitGroups = UnitGroup.entries, unitConverterFavoritesOnly = false, enableToolsExperiment = false, From 00ca88b1e67be49f3043031fc959482cda77e19b Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Sat, 13 Jul 2024 12:45:16 +0200 Subject: [PATCH 06/27] feat: Add animation to ConverterKeyboard.kt Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../converter/components/ConverterKeyboard.kt | 79 +++++++++++++------ 1 file changed, 56 insertions(+), 23 deletions(-) diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt index 29cff357..33469257 100644 --- a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt @@ -18,6 +18,10 @@ package app.myzel394.numberhub.feature.converter.components +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.AnimatedContentTransitionScope +import androidx.compose.animation.core.tween +import androidx.compose.animation.togetherWith import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Row @@ -25,7 +29,11 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource @@ -163,34 +171,57 @@ internal fun NumberBaseKeyboard( basis: BasicUnit.NumberBase, ) { val contentHeight: Float = if (LocalWindowSize.current.heightSizeClass < WindowHeightSizeClass.Medium) KeyboardButtonToken.CONTENT_HEIGHT_SHORT else KeyboardButtonToken.CONTENT_HEIGHT_TALL - val amount = basis.factor.toInt() - - val columns: Int = when { - amount == 5 -> 2 - amount == 3 -> 2 - amount == 7 -> 2 - amount == 10 -> 3 - amount < 10 -> if (amount.and(1) == 0) 2 else if (amount % 3 == 0) 3 else amount % 3 - else -> 3 + + var direction by remember { + mutableStateOf(AnimatedContentTransitionScope.SlideDirection.Right) } - val rows = when { - amount == 5 -> 3 - amount == 3 -> 2 - amount == 7 -> 4 - amount == 10 -> 4 - amount < 10 -> ceil(amount.toDouble() / columns.toDouble()).toInt() + 1 - amount == 11 -> 5 - amount == 12 -> 5 - amount == 13 -> 5 - else -> 6 + + LaunchedEffect(basis) { + when (direction) { + AnimatedContentTransitionScope.SlideDirection.Left -> { + direction = AnimatedContentTransitionScope.SlideDirection.Right + } + + AnimatedContentTransitionScope.SlideDirection.Right -> { + direction = AnimatedContentTransitionScope.SlideDirection.Left + } + } } ColumnWithConstraints(Modifier) { constraints -> - val horizontalSpacing = 8.dp - val verticalSpacing = 12.dp - val height: Float = (1f - (verticalSpacing * (rows - 1) / constraints.maxHeight)) / rows + AnimatedContent( + transitionSpec = { + slideIntoContainer(animationSpec = tween(600), towards = direction).togetherWith( + slideOutOfContainer(animationSpec = tween(600), towards = direction), + ) + }, + targetState = basis.factor.toInt(), + label = "ConverterKeyboard-FlowRow", + ) { amount -> + val columns: Int = when { + amount == 5 -> 2 + amount == 3 -> 2 + amount == 7 -> 2 + amount == 10 -> 3 + amount < 10 -> if (amount.and(1) == 0) 2 else if (amount % 3 == 0) 3 else amount % 3 + else -> 3 + } + val rows = when { + amount == 5 -> 3 + amount == 3 -> 2 + amount == 7 -> 4 + amount == 10 -> 4 + amount < 10 -> ceil(amount.toDouble() / columns.toDouble()).toInt() + 1 + amount == 11 -> 5 + amount == 12 -> 5 + amount == 13 -> 5 + else -> 6 + } + val horizontalSpacing = 8.dp + val verticalSpacing = 12.dp + val height: Float = (1f - (verticalSpacing * (rows - 1) / constraints.maxHeight)) / rows - FlowRow( + FlowRow( modifier = modifier, maxItemsInEachRow = columns, horizontalArrangement = Arrangement.spacedBy(horizontalSpacing), @@ -329,6 +360,8 @@ internal fun NumberBaseKeyboard( } } } + + } } } From 38ba85abaa4820eaf26fad6694fec82daf5db2df Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Sat, 13 Jul 2024 13:44:17 +0200 Subject: [PATCH 07/27] fix: Improve animation for ConverterKeyboard.kt Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../converter/components/ConverterKeyboard.kt | 434 ++++++++++++------ 1 file changed, 282 insertions(+), 152 deletions(-) diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt index 33469257..9a47e2c4 100644 --- a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt @@ -43,6 +43,7 @@ import app.myzel394.numberhub.core.base.R import app.myzel394.numberhub.core.base.Token import app.myzel394.numberhub.core.ui.LocalWindowSize import app.myzel394.numberhub.core.ui.WindowHeightSizeClass +import app.myzel394.numberhub.core.ui.WindowWidthSizeClass import app.myzel394.numberhub.core.ui.common.ColumnWithConstraints import app.myzel394.numberhub.core.ui.common.KeyboardButtonFilled import app.myzel394.numberhub.core.ui.common.KeyboardButtonLight @@ -95,7 +96,8 @@ internal fun DefaultKeyboard( ) { 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) KeyboardButtonToken.CONTENT_HEIGHT_SHORT else KeyboardButtonToken.CONTENT_HEIGHT_TALL + val height: Float = + if (LocalWindowSize.current.heightSizeClass < WindowHeightSizeClass.Medium) KeyboardButtonToken.CONTENT_HEIGHT_SHORT else KeyboardButtonToken.CONTENT_HEIGHT_TALL KeypadFlow( modifier = modifier, @@ -107,39 +109,160 @@ internal fun DefaultKeyboard( .fillMaxHeight(height) if (acButton) { - KeyboardButtonTertiary(bModifier, IconPack.Clear, stringResource(R.string.delete_label), contentHeight) { clearInput() } - KeyboardButtonFilled(bModifier, IconPack.Brackets, stringResource(R.string.keyboard_brackets), contentHeight) { addBracket() } + KeyboardButtonTertiary( + bModifier, + IconPack.Clear, + stringResource(R.string.delete_label), + height, + ) { clearInput() } + KeyboardButtonFilled( + bModifier, + IconPack.Brackets, + stringResource(R.string.keyboard_brackets), + height, + ) { addBracket() } } else { - KeyboardButtonFilled(bModifier, IconPack.LeftBracket, stringResource(R.string.keyboard_left_bracket), contentHeight) { addDigit(Token.Operator.leftBracket) } - KeyboardButtonFilled(bModifier, IconPack.RightBracket, stringResource(R.string.keyboard_right_bracket), contentHeight) { addDigit(Token.Operator.rightBracket) } + KeyboardButtonFilled( + bModifier, + IconPack.LeftBracket, + stringResource(R.string.keyboard_left_bracket), + height, + ) { addDigit(Token.Operator.leftBracket) } + KeyboardButtonFilled( + bModifier, + IconPack.RightBracket, + stringResource(R.string.keyboard_right_bracket), + height, + ) { addDigit(Token.Operator.rightBracket) } } - KeyboardButtonFilled(bModifier, IconPack.Power, stringResource(R.string.keyboard_power), contentHeight) { addDigit(Token.Operator.power) } - KeyboardButtonFilled(bModifier, IconPack.Root, stringResource(R.string.keyboard_root), contentHeight) { addDigit(Token.Operator.sqrt) } - - KeyboardButtonLight(bModifier, IconPack.Key7, Token.Digit._7, contentHeight) { addDigit(Token.Digit._7) } - KeyboardButtonLight(bModifier, IconPack.Key8, Token.Digit._8, contentHeight) { addDigit(Token.Digit._8) } - KeyboardButtonLight(bModifier, IconPack.Key9, Token.Digit._9, contentHeight) { addDigit(Token.Digit._9) } - KeyboardButtonFilled(bModifier, IconPack.Divide, stringResource(R.string.keyboard_divide), contentHeight) { addDigit(Token.Operator.divide) } - - KeyboardButtonLight(bModifier, IconPack.Key4, Token.Digit._4, contentHeight) { addDigit(Token.Digit._4) } - KeyboardButtonLight(bModifier, IconPack.Key5, Token.Digit._5, contentHeight) { addDigit(Token.Digit._5) } - KeyboardButtonLight(bModifier, IconPack.Key6, Token.Digit._6, contentHeight) { addDigit(Token.Digit._6) } - KeyboardButtonFilled(bModifier, IconPack.Multiply, stringResource(R.string.keyboard_multiply), contentHeight) { addDigit(Token.Operator.multiply) } - - KeyboardButtonLight(bModifier, IconPack.Key1, Token.Digit._1, contentHeight) { addDigit(Token.Digit._1) } - KeyboardButtonLight(bModifier, IconPack.Key2, Token.Digit._2, contentHeight) { addDigit(Token.Digit._2) } - KeyboardButtonLight(bModifier, IconPack.Key3, Token.Digit._3, contentHeight) { addDigit(Token.Digit._3) } - KeyboardButtonFilled(bModifier, IconPack.Minus, stringResource(R.string.keyboard_minus), contentHeight) { addDigit(Token.Operator.minus) } + KeyboardButtonFilled( + bModifier, + IconPack.Power, + stringResource(R.string.keyboard_power), + height, + ) { addDigit(Token.Operator.power) } + KeyboardButtonFilled( + bModifier, + IconPack.Root, + stringResource(R.string.keyboard_root), + height, + ) { addDigit(Token.Operator.sqrt) } + + KeyboardButtonLight( + bModifier, + IconPack.Key7, + Token.Digit._7, + height, + ) { addDigit(Token.Digit._7) } + KeyboardButtonLight( + bModifier, + IconPack.Key8, + Token.Digit._8, + height, + ) { addDigit(Token.Digit._8) } + KeyboardButtonLight( + bModifier, + IconPack.Key9, + Token.Digit._9, + height, + ) { addDigit(Token.Digit._9) } + KeyboardButtonFilled( + bModifier, + IconPack.Divide, + stringResource(R.string.keyboard_divide), + height, + ) { addDigit(Token.Operator.divide) } + + KeyboardButtonLight( + bModifier, + IconPack.Key4, + Token.Digit._4, + height, + ) { addDigit(Token.Digit._4) } + KeyboardButtonLight( + bModifier, + IconPack.Key5, + Token.Digit._5, + height, + ) { addDigit(Token.Digit._5) } + KeyboardButtonLight( + bModifier, + IconPack.Key6, + Token.Digit._6, + height, + ) { addDigit(Token.Digit._6) } + KeyboardButtonFilled( + bModifier, + IconPack.Multiply, + stringResource(R.string.keyboard_multiply), + height, + ) { addDigit(Token.Operator.multiply) } + + KeyboardButtonLight( + bModifier, + IconPack.Key1, + Token.Digit._1, + height, + ) { addDigit(Token.Digit._1) } + KeyboardButtonLight( + bModifier, + IconPack.Key2, + Token.Digit._2, + height, + ) { addDigit(Token.Digit._2) } + KeyboardButtonLight( + bModifier, + IconPack.Key3, + Token.Digit._3, + height, + ) { addDigit(Token.Digit._3) } + KeyboardButtonFilled( + bModifier, + IconPack.Minus, + stringResource(R.string.keyboard_minus), + height, + ) { addDigit(Token.Operator.minus) } if (middleZero) { - KeyboardButtonLight(bModifier, fractionalIcon, stringResource(fractionalIconDescription), contentHeight) { addDigit(Token.Digit.dot) } - KeyboardButtonLight(bModifier, IconPack.Key0, Token.Digit._0, contentHeight) { addDigit(Token.Digit._0) } + KeyboardButtonLight( + bModifier, + fractionalIcon, + stringResource(fractionalIconDescription), + height, + ) { addDigit(Token.Digit.dot) } + KeyboardButtonLight( + bModifier, + IconPack.Key0, + Token.Digit._0, + height, + ) { addDigit(Token.Digit._0) } } else { - KeyboardButtonLight(bModifier, IconPack.Key0, Token.Digit._0, contentHeight) { addDigit(Token.Digit._0) } - KeyboardButtonLight(bModifier, fractionalIcon, stringResource(fractionalIconDescription), contentHeight) { addDigit(Token.Digit.dot) } + KeyboardButtonLight( + bModifier, + IconPack.Key0, + Token.Digit._0, + height, + ) { addDigit(Token.Digit._0) } + KeyboardButtonLight( + bModifier, + fractionalIcon, + stringResource(fractionalIconDescription), + height, + ) { addDigit(Token.Digit.dot) } } - KeyboardButtonLight(bModifier, IconPack.Backspace, stringResource(R.string.delete_label), contentHeight, onLongClick = clearInput) { deleteDigit() } - KeyboardButtonFilled(bModifier, IconPack.Plus, stringResource(R.string.keyboard_plus), contentHeight) { addDigit(Token.Operator.plus) } + KeyboardButtonLight( + bModifier, + IconPack.Backspace, + stringResource(R.string.delete_label), + height, + onLongClick = clearInput, + ) { deleteDigit() } + KeyboardButtonFilled( + bModifier, + IconPack.Plus, + stringResource(R.string.keyboard_plus), + height, + ) { addDigit(Token.Operator.plus) } } } @@ -171,24 +294,32 @@ internal fun NumberBaseKeyboard( basis: BasicUnit.NumberBase, ) { val contentHeight: Float = if (LocalWindowSize.current.heightSizeClass < WindowHeightSizeClass.Medium) KeyboardButtonToken.CONTENT_HEIGHT_SHORT else KeyboardButtonToken.CONTENT_HEIGHT_TALL + val isUsingColumn = + (LocalWindowSize.current.widthSizeClass > WindowWidthSizeClass.Expanded) or (LocalWindowSize.current.heightSizeClass > WindowHeightSizeClass.Compact) var direction by remember { mutableStateOf(AnimatedContentTransitionScope.SlideDirection.Right) } - LaunchedEffect(basis) { - when (direction) { - AnimatedContentTransitionScope.SlideDirection.Left -> { - direction = AnimatedContentTransitionScope.SlideDirection.Right - } + LaunchedEffect(isUsingColumn) { + direction = if (isUsingColumn) { + AnimatedContentTransitionScope.SlideDirection.Right + } else { + AnimatedContentTransitionScope.SlideDirection.Up + } + } - AnimatedContentTransitionScope.SlideDirection.Right -> { - direction = AnimatedContentTransitionScope.SlideDirection.Left - } + LaunchedEffect(basis) { + direction = when (direction) { + AnimatedContentTransitionScope.SlideDirection.Up -> AnimatedContentTransitionScope.SlideDirection.Down + AnimatedContentTransitionScope.SlideDirection.Down -> AnimatedContentTransitionScope.SlideDirection.Up + AnimatedContentTransitionScope.SlideDirection.Left -> AnimatedContentTransitionScope.SlideDirection.Right + AnimatedContentTransitionScope.SlideDirection.Right -> AnimatedContentTransitionScope.SlideDirection.Left + else -> direction } } - ColumnWithConstraints(Modifier) { constraints -> + ColumnWithConstraints(modifier) { constraints -> AnimatedContent( transitionSpec = { slideIntoContainer(animationSpec = tween(600), towards = direction).togetherWith( @@ -222,146 +353,145 @@ internal fun NumberBaseKeyboard( val height: Float = (1f - (verticalSpacing * (rows - 1) / constraints.maxHeight)) / rows FlowRow( - modifier = modifier, - maxItemsInEachRow = columns, - horizontalArrangement = Arrangement.spacedBy(horizontalSpacing), - verticalArrangement = Arrangement.spacedBy(verticalSpacing), - ) { - val bModifier = Modifier - .fillMaxHeight(height) - .fillMaxWidth() - - when { - amount in arrayOf(3, 5, 7) -> { - for (int in createSortedArray(1.. { + for (int in createSortedArray(1.. { + for (int in createSortedArray(0.. { - for (int in createSortedArray(0.. { + for (int in createSortedArray(1..9, columns)) { + val key = AVAILABLE_NUMBERS.keys.elementAt(int) + val icon = AVAILABLE_NUMBERS[key]!! + KeyboardButtonLight( + bModifier.weight(1f), + icon, + key, + contentHeight, + ) { addDigit(key) } + } - amount == 10 -> { - for (int in createSortedArray(1..9, columns)) { - val key = AVAILABLE_NUMBERS.keys.elementAt(int) - val icon = AVAILABLE_NUMBERS[key]!! KeyboardButtonLight( bModifier.weight(1f), - icon, - key, + IconPack.Key0, + Token.Digit._0, + contentHeight, + ) { addDigit(Token.Digit._0) } + KeyboardButtonTertiary( + bModifier.weight(2f), + IconPack.Backspace, + stringResource(R.string.delete_label), contentHeight, - ) { addDigit(key) } + clearInput, + ) { deleteDigit() } } - KeyboardButtonLight( - bModifier.weight(1f), - IconPack.Key0, - Token.Digit._0, - contentHeight, - ) { addDigit(Token.Digit._0) } - KeyboardButtonTertiary( - bModifier.weight(2f), - IconPack.Backspace, - stringResource(R.string.delete_label), - contentHeight, - clearInput, - ) { deleteDigit() } - } - - else -> { - val lettersAmount = (10.. { + val lettersAmount = (10.. Date: Sat, 13 Jul 2024 16:01:27 +0200 Subject: [PATCH 08/27] fix: Improve ConverterKeyboard.kt Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../converter/components/ConverterKeyboard.kt | 23 +---------------- .../numberhub/feature/converter/utils.kt | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 22 deletions(-) create mode 100644 feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/utils.kt diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt index 9a47e2c4..a9be920e 100644 --- a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt @@ -81,6 +81,7 @@ import app.myzel394.numberhub.core.ui.common.icons.iconpack.Power import app.myzel394.numberhub.core.ui.common.icons.iconpack.RightBracket import app.myzel394.numberhub.core.ui.common.icons.iconpack.Root import app.myzel394.numberhub.data.model.converter.unit.BasicUnit +import app.myzel394.numberhub.feature.converter.createSortedArray import kotlin.math.ceil @Composable @@ -521,25 +522,3 @@ private fun PreviewConverterKeyboardNumberBase() { basis = BasicUnit.NumberBase.Hexadecimal, ) } - -// So here's the problem. If we just go down from 3 downto 0 with columns 2, this results in: -// [3, 2] -// [1, 0] -// While this is correct, the ordering is incorrect. It should be -// [2, 3] -// [0, 1] -// TODO: Add support for rtl languages -internal fun createSortedArray(range: IntRange, columns: Int): List { - val result = mutableListOf() - val rows = ceil(range.count().toDouble() / columns.toDouble()).toInt() - for (row in rows downTo 0) { - for (column in 0 until columns) { - val index = row * columns + column + range.first - if (index <= range.last) { - result.add(index) - } - } - } - - return result -} diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/utils.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/utils.kt new file mode 100644 index 00000000..3b7cbc91 --- /dev/null +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/utils.kt @@ -0,0 +1,25 @@ +package app.myzel394.numberhub.feature.converter + +import kotlin.math.ceil + +// So here's the problem. If we just go down from 3 downto 0 with columns 2, this results in: +// [3, 2] +// [1, 0] +// While this is correct, the ordering is incorrect. It should be +// [2, 3] +// [0, 1] +// TODO: Add support for rtl languages +internal fun createSortedArray(range: IntRange, columns: Int): List { + val result = mutableListOf() + val rows = ceil(range.count().toDouble() / columns.toDouble()).toInt() + for (row in rows downTo 0) { + for (column in 0 until columns) { + val index = row * columns + column + range.first + if (index <= range.last) { + result.add(index) + } + } + } + + return result +} From 2097ab593b8c527d6ec7465b4b49f38d33ad7a64 Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Sat, 13 Jul 2024 16:02:07 +0200 Subject: [PATCH 09/27] feat: Add base calculation summary underneath converter Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../feature/converter/ConverterScreen.kt | 43 ++++++++++++- .../numberhub/feature/converter/DragState.kt | 3 + .../components/BaseCalculationSummary.kt | 61 +++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/DragState.kt create mode 100644 feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/BaseCalculationSummary.kt diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt index 4039d8cb..a8df6824 100644 --- a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt @@ -22,6 +22,7 @@ import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.SizeTransform import androidx.compose.animation.core.FastOutSlowInEasing +import androidx.compose.animation.core.LinearEasing import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.tween import androidx.compose.animation.expandHorizontally @@ -31,6 +32,11 @@ import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkVertically import androidx.compose.animation.togetherWith import androidx.compose.foundation.background +import androidx.compose.foundation.gestures.AnchoredDraggableState +import androidx.compose.foundation.gestures.DraggableAnchors +import androidx.compose.foundation.gestures.Orientation +import androidx.compose.foundation.gestures.anchoredDraggable +import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues @@ -40,6 +46,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.SwapHoriz @@ -64,6 +71,7 @@ import androidx.compose.ui.draw.rotate import androidx.compose.ui.focus.onFocusEvent import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextAlign @@ -94,11 +102,13 @@ import app.myzel394.numberhub.data.common.isExpression import app.myzel394.numberhub.data.converter.ConverterResult import app.myzel394.numberhub.data.converter.UnitID import app.myzel394.numberhub.data.model.converter.UnitGroup +import app.myzel394.numberhub.feature.converter.components.BaseCalculationSummary import app.myzel394.numberhub.feature.converter.components.DefaultKeyboard import app.myzel394.numberhub.feature.converter.components.NumberBaseKeyboard import app.myzel394.numberhub.feature.converter.components.UnitSelectionButton import java.math.BigDecimal import java.util.Locale +import kotlin.math.absoluteValue @Composable internal fun ConverterRoute( @@ -203,10 +213,30 @@ private fun NumberBase( convert() } + val density = LocalDensity.current + val dragState = remember { + AnchoredDraggableState( + initialValue = DragState.CLOSED, + anchors = DraggableAnchors { + DragState.CLOSED at 0f + DragState.OPEN at with(density) { -60.dp.toPx() } + }, + positionalThreshold = { 0f }, + velocityThreshold = { 0f }, + animationSpec = tween(easing = LinearEasing, durationMillis = 50), + ) + } + PortraitLandscape( modifier = modifier.fillMaxSize(), content1 = { contentModifier -> - ColumnWithConstraints(modifier = contentModifier) { + ColumnWithConstraints( + modifier = contentModifier + .anchoredDraggable( + state = dragState, + orientation = Orientation.Vertical, + ), + ) { val textFieldModifier = Modifier.weight(2f) NumberBaseTextField( @@ -224,6 +254,17 @@ private fun NumberBase( ) AnimatedUnitShortName(stringResource(uiState.unitTo.shortName)) + if (uiState.result is ConverterResult.NumberBase) { + BaseCalculationSummary( + modifier = Modifier + .fillMaxWidth() + .horizontalScroll(rememberScrollState()) + .then(with(density) { Modifier.height(dragState.offset.absoluteValue.toDp()) }), + basis = uiState.unitTo, + result = uiState.result, + ) + } + Spacer(modifier = Modifier.height(it.maxHeight * 0.03f)) UnitSelectionButtons( diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/DragState.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/DragState.kt new file mode 100644 index 00000000..50e2cb4c --- /dev/null +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/DragState.kt @@ -0,0 +1,3 @@ +package app.myzel394.numberhub.feature.converter + +internal enum class DragState { CLOSED, OPEN } diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/BaseCalculationSummary.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/BaseCalculationSummary.kt new file mode 100644 index 00000000..9cd784e3 --- /dev/null +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/BaseCalculationSummary.kt @@ -0,0 +1,61 @@ +package app.myzel394.numberhub.feature.converter.components + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.offset +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import app.myzel394.numberhub.data.converter.ConverterResult +import app.myzel394.numberhub.data.model.converter.unit.BasicUnit + +@Composable +internal fun BaseCalculationSummary( + modifier: Modifier = Modifier, + basis: BasicUnit.NumberBase, + result: ConverterResult.NumberBase, +) { + val fontStyle = MaterialTheme.typography.headlineSmall + + Row( + modifier, + horizontalArrangement = Arrangement.End, + verticalAlignment = Alignment.CenterVertically, + ) { + for (index in 0.. Date: Sat, 13 Jul 2024 16:17:00 +0200 Subject: [PATCH 10/27] feat: Add single digit change feature for calculation summary Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../feature/converter/ConverterScreen.kt | 5 ++ .../components/BaseCalculationSummary.kt | 61 +++++++++++++------ 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt index a8df6824..2be2a7d6 100644 --- a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt @@ -262,6 +262,11 @@ private fun NumberBase( .then(with(density) { Modifier.height(dragState.offset.absoluteValue.toDp()) }), basis = uiState.unitTo, result = uiState.result, + onResultChange = { newValue -> + val valueConverted = uiState.unitTo.convert(uiState.unitFrom, newValue) + + updateInput1(TextFieldValue(valueConverted)) + }, ) } diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/BaseCalculationSummary.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/BaseCalculationSummary.kt index 9cd784e3..e4fa3632 100644 --- a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/BaseCalculationSummary.kt +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/BaseCalculationSummary.kt @@ -1,13 +1,16 @@ package app.myzel394.numberhub.feature.converter.components +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import app.myzel394.numberhub.data.converter.ConverterResult import app.myzel394.numberhub.data.model.converter.unit.BasicUnit @@ -17,6 +20,7 @@ internal fun BaseCalculationSummary( modifier: Modifier = Modifier, basis: BasicUnit.NumberBase, result: ConverterResult.NumberBase, + onResultChange: (String) -> Unit, ) { val fontStyle = MaterialTheme.typography.headlineSmall @@ -30,24 +34,45 @@ internal fun BaseCalculationSummary( val digit = character.digitToInt(16); val base = basis.factor.toInt() - Text( - text = "$digit", - style = fontStyle, - color = MaterialTheme.colorScheme.primary, - ) - Text( - text = " · $base", - style = fontStyle, - color = MaterialTheme.colorScheme.onSurfaceVariant, - ) - Text( - text = "${result.value.length - index - 1}", - modifier = Modifier.offset(y = -(MaterialTheme.typography.bodySmall.fontSize.div(2)).value.dp), - style = fontStyle.copy( - fontSize = MaterialTheme.typography.bodySmall.fontSize, - ), - color = MaterialTheme.colorScheme.tertiary, - ) + Row( + modifier = Modifier + .clip(MaterialTheme.shapes.small) + .clickable { + val newCurrentValue = (digit + 1) % base + val newResultText = result.value.substring( + 0, + index, + ) + newCurrentValue.toString(16) + result.value.substring(index + 1) + + onResultChange(newResultText) + } + .padding(vertical = 2.dp, horizontal = 6.dp), + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = "$digit", + style = fontStyle, + color = MaterialTheme.colorScheme.primary, + ) + Text( + text = " · $base", + style = fontStyle, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + Text( + text = "${result.value.length - index - 1}", + modifier = Modifier.offset( + y = -(MaterialTheme.typography.bodySmall.fontSize.div( + 2, + )).value.dp, + ), + style = fontStyle.copy( + fontSize = MaterialTheme.typography.bodySmall.fontSize, + ), + color = MaterialTheme.colorScheme.tertiary, + ) + } if (index < result.value.length - 1) { Text( From 305744f9d56bc59f472b4e4b06224b2df81ff950 Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Sat, 13 Jul 2024 16:22:59 +0200 Subject: [PATCH 11/27] fix: Fix size Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../converter/components/ConverterKeyboard.kt | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt index a9be920e..cd343f43 100644 --- a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt @@ -97,7 +97,7 @@ internal fun DefaultKeyboard( ) { 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 height: Float = + val contentHeight: Float = if (LocalWindowSize.current.heightSizeClass < WindowHeightSizeClass.Medium) KeyboardButtonToken.CONTENT_HEIGHT_SHORT else KeyboardButtonToken.CONTENT_HEIGHT_TALL KeypadFlow( @@ -114,114 +114,114 @@ internal fun DefaultKeyboard( bModifier, IconPack.Clear, stringResource(R.string.delete_label), - height, + contentHeight, ) { clearInput() } KeyboardButtonFilled( bModifier, IconPack.Brackets, stringResource(R.string.keyboard_brackets), - height, + contentHeight, ) { addBracket() } } else { KeyboardButtonFilled( bModifier, IconPack.LeftBracket, stringResource(R.string.keyboard_left_bracket), - height, + contentHeight, ) { addDigit(Token.Operator.leftBracket) } KeyboardButtonFilled( bModifier, IconPack.RightBracket, stringResource(R.string.keyboard_right_bracket), - height, + contentHeight, ) { addDigit(Token.Operator.rightBracket) } } KeyboardButtonFilled( bModifier, IconPack.Power, stringResource(R.string.keyboard_power), - height, + contentHeight, ) { addDigit(Token.Operator.power) } KeyboardButtonFilled( bModifier, IconPack.Root, stringResource(R.string.keyboard_root), - height, + contentHeight, ) { addDigit(Token.Operator.sqrt) } KeyboardButtonLight( bModifier, IconPack.Key7, Token.Digit._7, - height, + contentHeight, ) { addDigit(Token.Digit._7) } KeyboardButtonLight( bModifier, IconPack.Key8, Token.Digit._8, - height, + contentHeight, ) { addDigit(Token.Digit._8) } KeyboardButtonLight( bModifier, IconPack.Key9, Token.Digit._9, - height, + contentHeight, ) { addDigit(Token.Digit._9) } KeyboardButtonFilled( bModifier, IconPack.Divide, stringResource(R.string.keyboard_divide), - height, + contentHeight, ) { addDigit(Token.Operator.divide) } KeyboardButtonLight( bModifier, IconPack.Key4, Token.Digit._4, - height, + contentHeight, ) { addDigit(Token.Digit._4) } KeyboardButtonLight( bModifier, IconPack.Key5, Token.Digit._5, - height, + contentHeight, ) { addDigit(Token.Digit._5) } KeyboardButtonLight( bModifier, IconPack.Key6, Token.Digit._6, - height, + contentHeight, ) { addDigit(Token.Digit._6) } KeyboardButtonFilled( bModifier, IconPack.Multiply, stringResource(R.string.keyboard_multiply), - height, + contentHeight, ) { addDigit(Token.Operator.multiply) } KeyboardButtonLight( bModifier, IconPack.Key1, Token.Digit._1, - height, + contentHeight, ) { addDigit(Token.Digit._1) } KeyboardButtonLight( bModifier, IconPack.Key2, Token.Digit._2, - height, + contentHeight, ) { addDigit(Token.Digit._2) } KeyboardButtonLight( bModifier, IconPack.Key3, Token.Digit._3, - height, + contentHeight, ) { addDigit(Token.Digit._3) } KeyboardButtonFilled( bModifier, IconPack.Minus, stringResource(R.string.keyboard_minus), - height, + contentHeight, ) { addDigit(Token.Operator.minus) } if (middleZero) { @@ -229,40 +229,40 @@ internal fun DefaultKeyboard( bModifier, fractionalIcon, stringResource(fractionalIconDescription), - height, + contentHeight, ) { addDigit(Token.Digit.dot) } KeyboardButtonLight( bModifier, IconPack.Key0, Token.Digit._0, - height, + contentHeight, ) { addDigit(Token.Digit._0) } } else { KeyboardButtonLight( bModifier, IconPack.Key0, Token.Digit._0, - height, + contentHeight, ) { addDigit(Token.Digit._0) } KeyboardButtonLight( bModifier, fractionalIcon, stringResource(fractionalIconDescription), - height, + contentHeight, ) { addDigit(Token.Digit.dot) } } KeyboardButtonLight( bModifier, IconPack.Backspace, stringResource(R.string.delete_label), - height, + contentHeight, onLongClick = clearInput, ) { deleteDigit() } KeyboardButtonFilled( bModifier, IconPack.Plus, stringResource(R.string.keyboard_plus), - height, + contentHeight, ) { addDigit(Token.Operator.plus) } } } From 855f620548451950cea513da20682be88140d7ff Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Sat, 13 Jul 2024 16:45:25 +0200 Subject: [PATCH 12/27] feat: Add information for value of 1 for conversions Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../feature/converter/ConverterScreen.kt | 33 ++++++++- .../converter/components/ValueOneSummary.kt | 74 +++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ValueOneSummary.kt diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt index 2be2a7d6..e87baa08 100644 --- a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt @@ -106,6 +106,7 @@ import app.myzel394.numberhub.feature.converter.components.BaseCalculationSummar import app.myzel394.numberhub.feature.converter.components.DefaultKeyboard import app.myzel394.numberhub.feature.converter.components.NumberBaseKeyboard import app.myzel394.numberhub.feature.converter.components.UnitSelectionButton +import app.myzel394.numberhub.feature.converter.components.ValueOneSummary import java.math.BigDecimal import java.util.Locale import kotlin.math.absoluteValue @@ -331,6 +332,20 @@ private fun Default( } var focusedOnInput1 by rememberSaveable { mutableStateOf(true) } + val density = LocalDensity.current + val dragState = remember { + AnchoredDraggableState( + initialValue = DragState.CLOSED, + anchors = DraggableAnchors { + DragState.CLOSED at 0f + DragState.OPEN at with(density) { -60.dp.toPx() } + }, + positionalThreshold = { 0f }, + velocityThreshold = { 0f }, + animationSpec = tween(easing = LinearEasing, durationMillis = 50), + ) + } + LaunchedEffect(connection) { if ((connection == ConnectionState.Available) and (uiState.result is ConverterResult.Error)) { val unitFrom = uiState.unitFrom @@ -351,7 +366,13 @@ private fun Default( PortraitLandscape( modifier = modifier.fillMaxSize(), content1 = { contentModifier -> - ColumnWithConstraints(modifier = contentModifier) { boxWithConstraintsScope -> + ColumnWithConstraints( + modifier = contentModifier + .anchoredDraggable( + state = dragState, + orientation = Orientation.Vertical, + ), + ) { boxWithConstraintsScope -> val textFieldModifier = Modifier .fillMaxWidth() .weight(2f) @@ -472,6 +493,16 @@ private fun Default( ), ) + ValueOneSummary( + modifier = with(density) { + Modifier + .fillMaxWidth() + .height(dragState.offset.absoluteValue.toDp()) + .horizontalScroll(rememberScrollState()) + }, + uiState = uiState, + ) + Spacer(modifier = Modifier.height(boxWithConstraintsScope.maxHeight * 0.03f)) UnitSelectionButtons( diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ValueOneSummary.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ValueOneSummary.kt new file mode 100644 index 00000000..fa02601f --- /dev/null +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ValueOneSummary.kt @@ -0,0 +1,74 @@ +package app.myzel394.numberhub.feature.converter.components + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import app.myzel394.numberhub.data.common.format +import app.myzel394.numberhub.feature.converter.UnitConverterUIState +import java.math.BigDecimal + +@Composable +internal fun ValueOneSummary( + modifier: Modifier = Modifier, + uiState: UnitConverterUIState.Default, +) { + val unitFromLabel = LocalContext.current.getString(uiState.unitFrom.displayName) + val unitToLabel = LocalContext.current.getString(uiState.unitTo.displayName) + val value = uiState.unitFrom.convert(uiState.unitTo, BigDecimal(1)) + .format(uiState.scale, uiState.outputFormat) + + val fontStyle = MaterialTheme.typography.headlineSmall + + Row( + modifier = modifier, + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.End, + ) { + Text( + 1.toString(), + style = fontStyle, + color = MaterialTheme.colorScheme.primary, + ) + + Text( + " ", + style = fontStyle, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + + Text( + unitFromLabel, + style = fontStyle, + color = MaterialTheme.colorScheme.tertiary, + ) + + Text( + " = ", + style = fontStyle, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + + Text( + value, + style = fontStyle, + color = MaterialTheme.colorScheme.primary, + ) + + Text( + " ", + style = fontStyle, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + + Text( + unitToLabel, + style = fontStyle, + color = MaterialTheme.colorScheme.tertiary, + ) + } +} \ No newline at end of file From ab4c8a896379df146d28a0d8da15c5c54433491e Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Sat, 13 Jul 2024 21:56:06 +0200 Subject: [PATCH 13/27] feat: Add opinionated unit pairings Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../data/converter/UnitsRepositoryImpl.kt | 229 +++++++++++++++++- 1 file changed, 222 insertions(+), 7 deletions(-) diff --git a/data/converter/src/main/java/app/myzel394/numberhub/data/converter/UnitsRepositoryImpl.kt b/data/converter/src/main/java/app/myzel394/numberhub/data/converter/UnitsRepositoryImpl.kt index 4931cb0a..37c69af6 100644 --- a/data/converter/src/main/java/app/myzel394/numberhub/data/converter/UnitsRepositoryImpl.kt +++ b/data/converter/src/main/java/app/myzel394/numberhub/data/converter/UnitsRepositoryImpl.kt @@ -102,17 +102,232 @@ class UnitsRepositoryImpl @Inject constructor( suspend fun getPairId(id: String): String = withContext(Dispatchers.IO) { val basedUnitPair = getUnitStats(id).pairedUnitId - if (basedUnitPair != null) return@withContext basedUnitPair + if (basedUnitPair != null) { + return@withContext basedUnitPair + } val inMemoryUnit = inMemory.first { it.id == id } val collection = inMemory.filter { it.group == inMemoryUnit.group } - val pair = collection - .map { getById(it.id) to getUnitStats(it.id) } - .sortedByDescending { it.second.frequency } - .firstOrNull { it.second.isFavorite }?.first ?: collection.first() - - return@withContext pair.id + return@withContext when (inMemoryUnit.id) { + // === === === Length === === === + UnitID.nanometer -> UnitID.micrometer + UnitID.micrometer -> UnitID.millimeter + UnitID.millimeter -> UnitID.centimeter + + UnitID.centimeter -> UnitID.inch + UnitID.inch -> UnitID.centimeter + UnitID.decimeter -> UnitID.centimeter + UnitID.foot -> UnitID.meter + UnitID.yard -> UnitID.meter + UnitID.meter -> UnitID.foot + + UnitID.kilometer -> UnitID.mile + UnitID.mile -> UnitID.kilometer + UnitID.nautical_mile -> UnitID.kilometer + + UnitID.mercury_equatorial_radius -> UnitID.kilometer + UnitID.mars_equatorial_radius -> UnitID.kilometer + UnitID.venus_equatorial_radius -> UnitID.kilometer + UnitID.earth_equatorial_radius -> UnitID.kilometer + UnitID.neptune_equatorial_radius -> UnitID.kilometer + UnitID.uranus_equatorial_radius -> UnitID.kilometer + UnitID.saturn_equatorial_radius -> UnitID.kilometer + UnitID.jupiter_equatorial_radius -> UnitID.kilometer + UnitID.sun_equatorial_radius -> UnitID.kilometer + + UnitID.light_year -> UnitID.kilometer + + UnitID.parsec -> UnitID.light_year + UnitID.kiloparsec -> UnitID.parsec + UnitID.megaparsec -> UnitID.kiloparsec + + + // === === === Mass === === === + UnitID.electron_mass_rest -> UnitID.atomic_mass_unit + UnitID.atomic_mass_unit -> UnitID.electron_mass_rest + + UnitID.microgram -> UnitID.milligram + UnitID.milligram -> UnitID.gram + UnitID.grain -> UnitID.gram + UnitID.carat -> UnitID.gram + + UnitID.gram -> UnitID.carat + UnitID.ounce -> UnitID.gram + UnitID.pound -> UnitID.kilogram + UnitID.kilogram -> UnitID.pound + + UnitID.metric_ton -> UnitID.kilogram + UnitID.imperial_ton -> UnitID.pound + + UnitID.mercury_mass -> UnitID.kilogram + UnitID.mars_mass -> UnitID.kilogram + UnitID.venus_mass -> UnitID.kilogram + UnitID.earth_mass -> UnitID.kilogram + UnitID.uranus_mass -> UnitID.kilogram + UnitID.neptune_mass -> UnitID.kilogram + UnitID.saturn_mass -> UnitID.kilogram + UnitID.jupiter_mass -> UnitID.kilogram + UnitID.sun_mass -> UnitID.kilogram + + + // === === === Speed === === === + UnitID.millimeter_per_hour -> UnitID.millimeter_per_second + UnitID.millimeter_per_second -> UnitID.millimeter_per_hour + UnitID.millimeter_per_minute -> UnitID.millimeter_per_second + UnitID.centimeter_per_hour -> UnitID.centimeter_per_second + UnitID.centimeter_per_second -> UnitID.centimeter_per_hour + UnitID.centimeter_per_minute -> UnitID.centimeter_per_second + UnitID.meter_per_hour -> UnitID.meter_per_second + UnitID.meter_per_second -> UnitID.meter_per_hour + UnitID.meter_per_minute -> UnitID.meter_per_second + + UnitID.kilometer_per_hour -> UnitID.mile_per_hour + UnitID.kilometer_per_second -> UnitID.mile_per_second + UnitID.kilometer_per_minute -> UnitID.kilometer_per_second + UnitID.mile_per_hour -> UnitID.kilometer_per_hour + UnitID.mile_per_second -> UnitID.kilometer_per_second + UnitID.mile_per_minute -> UnitID.mile_per_second + + UnitID.foot_per_hour -> UnitID.foot_per_second + UnitID.foot_per_second -> UnitID.foot_per_hour + UnitID.foot_per_minute -> UnitID.foot_per_second + UnitID.yard_per_hour -> UnitID.yard_per_second + UnitID.yard_per_second -> UnitID.yard_per_hour + UnitID.yard_per_minute -> UnitID.yard_per_second + + UnitID.knot -> UnitID.kilometer_per_hour + UnitID.mach -> UnitID.kilometer_per_hour + UnitID.velocity_of_light_in_vacuum -> UnitID.kilometer_per_hour + UnitID.earths_orbital_speed -> UnitID.kilometer_per_hour + + UnitID.cosmic_velocity_first -> UnitID.kilometer_per_hour + UnitID.cosmic_velocity_second -> UnitID.kilometer_per_hour + UnitID.cosmic_velocity_third -> UnitID.kilometer_per_hour + + + // === === === Temperature === === === + UnitID.celsius -> UnitID.fahrenheit + UnitID.fahrenheit -> UnitID.celsius + UnitID.kelvin -> UnitID.celsius + + + // === === === Area === === === + UnitID.square_micrometer -> UnitID.square_millimeter + UnitID.square_millimeter -> UnitID.square_centimeter + UnitID.square_centimeter -> UnitID.square_meter + UnitID.square_decimeter -> UnitID.square_meter + UnitID.square_meter -> UnitID.square_kilometer + + UnitID.square_kilometer -> UnitID.square_meter + + UnitID.square_inch -> UnitID.square_foot + UnitID.square_foot -> UnitID.square_inch + UnitID.square_yard -> UnitID.square_meter + UnitID.square_mile -> UnitID.square_kilometer + + UnitID.acre -> UnitID.square_meter + UnitID.hectare -> UnitID.square_meter + UnitID.cent -> UnitID.square_meter + + + // === === === Time === === === + UnitID.attosecond -> UnitID.nanosecond + UnitID.nanosecond -> UnitID.microsecond + UnitID.microsecond -> UnitID.millisecond + UnitID.millisecond -> UnitID.second + + UnitID.jiffy -> UnitID.millisecond + + UnitID.second -> UnitID.millisecond + UnitID.minute -> UnitID.second + UnitID.hour -> UnitID.minute + UnitID.day -> UnitID.hour + UnitID.week -> UnitID.day + + + // === === === Data === === === + // TODO: Add tibibyte, exibyte + UnitID.bit -> UnitID.byte + UnitID.byte -> UnitID.kilobyte + UnitID.kilobyte -> UnitID.megabyte + UnitID.megabyte -> UnitID.gigabyte + UnitID.gigabyte -> UnitID.terabyte + UnitID.terabyte -> UnitID.petabyte + UnitID.petabyte -> UnitID.exabyte + + UnitID.kilobit -> UnitID.kilobyte + UnitID.megabit -> UnitID.megabyte + UnitID.gigabit -> UnitID.gigabyte + UnitID.terabit -> UnitID.terabyte + UnitID.petabit -> UnitID.petabyte + UnitID.exabit -> UnitID.exabyte + + UnitID.kibibit -> UnitID.kilobyte + UnitID.mebibit -> UnitID.megabyte + UnitID.gibibit -> UnitID.gigabyte + + UnitID.kibibyte -> UnitID.kilobyte + UnitID.mebibyte -> UnitID.megabyte + UnitID.gibibyte -> UnitID.gigabyte + + + // === === === Acceleration === === === + UnitID.millimeter_per_square_second -> UnitID.centimeter_per_square_second + UnitID.centimeter_per_square_second -> UnitID.meter_per_square_second + UnitID.decimeter_per_square_second -> UnitID.meter_per_square_second + UnitID.meter_per_square_second -> UnitID.kilometer_per_square_second + + UnitID.mercury_surface_gravity -> UnitID.meter_per_square_second + UnitID.mars_surface_gravity -> UnitID.meter_per_square_second + UnitID.venus_surface_gravity -> UnitID.meter_per_square_second + UnitID.uranus_surface_gravity -> UnitID.meter_per_square_second + UnitID.earth_surface_gravity -> UnitID.meter_per_square_second + UnitID.saturn_surface_gravity -> UnitID.meter_per_square_second + UnitID.neptune_surface_gravity -> UnitID.meter_per_square_second + UnitID.jupiter_surface_gravity -> UnitID.meter_per_square_second + UnitID.sun_surface_gravity -> UnitID.meter_per_square_second + + + // === === === Power === === === + UnitID.attowatt -> UnitID.watt + UnitID.watt -> UnitID.kilowatt + UnitID.kilowatt -> UnitID.watt + UnitID.megawatt -> UnitID.kilowatt + + + // === === === Angle === === === + UnitID.degree -> UnitID.radian + UnitID.radian -> UnitID.degree + + + // === === === Data Transfer === === === + UnitID.bit_per_second -> UnitID.byte_per_second + UnitID.kilobit_per_second -> UnitID.kilobyte_per_second + UnitID.megabit_per_second -> UnitID.megabyte_per_second + UnitID.gigabit_per_second -> UnitID.gigabyte_per_second + UnitID.terabit_per_second -> UnitID.terabyte_per_second + UnitID.petabit_per_second -> UnitID.petabyte_per_second + UnitID.exabit_per_second -> UnitID.exabyte_per_second + + UnitID.byte_per_second -> UnitID.kilobyte_per_second + UnitID.kilobyte_per_second -> UnitID.megabyte_per_second + UnitID.megabyte_per_second -> UnitID.gigabyte_per_second + UnitID.gigabyte_per_second -> UnitID.megabyte_per_second + UnitID.terabyte_per_second -> UnitID.gigabyte_per_second + UnitID.petabyte_per_second -> UnitID.terabyte_per_second + + + // === === === Fuel === === === + UnitID.kilometer_per_liter -> UnitID.mile_us_per_liter + UnitID.mile_us_per_liter -> UnitID.kilometer_per_liter + + else -> + (collection + .map { getById(it.id) to getUnitStats(it.id) } + .sortedByDescending { it.second.frequency } + .firstOrNull { it.second.isFavorite }?.first ?: collection.first()).id + } } suspend fun incrementCounter(id: String) = withContext(Dispatchers.IO) { From ad107b0143d5a4c5959a21a0388f40b71660cdca Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Sat, 13 Jul 2024 22:23:32 +0200 Subject: [PATCH 14/27] fix: Fix ConverterKeyboard.kt overflow Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../feature/converter/components/ConverterKeyboard.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt index cd343f43..327fa6dc 100644 --- a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/components/ConverterKeyboard.kt @@ -440,10 +440,9 @@ internal fun NumberBaseKeyboard( } else -> { - val lettersAmount = (10.. Date: Tue, 16 Jul 2024 20:41:37 +0200 Subject: [PATCH 15/27] fix: Only show ValueOneSummary if value is available Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../feature/converter/ConverterScreen.kt | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt index e87baa08..499a7cd3 100644 --- a/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt +++ b/feature/converter/src/main/java/app/myzel394/numberhub/feature/converter/ConverterScreen.kt @@ -493,15 +493,17 @@ private fun Default( ), ) - ValueOneSummary( - modifier = with(density) { - Modifier - .fillMaxWidth() - .height(dragState.offset.absoluteValue.toDp()) - .horizontalScroll(rememberScrollState()) - }, - uiState = uiState, - ) + if (uiState.result is ConverterResult.Default && uiState.unitTo.factor >= BigDecimal.ZERO) { + ValueOneSummary( + modifier = with(density) { + Modifier + .fillMaxWidth() + .height(dragState.offset.absoluteValue.toDp()) + .horizontalScroll(rememberScrollState()) + }, + uiState = uiState, + ) + } Spacer(modifier = Modifier.height(boxWithConstraintsScope.maxHeight * 0.03f)) From 1e2cc1ca2ea35f84c21e74e8c7f5c157386fc1a1 Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Fri, 19 Jul 2024 19:50:25 +0200 Subject: [PATCH 16/27] chore: Fix versionName Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- gradle/libs.versions.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9c5cc044..c00433f1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] -versionCode = "4" -versionName = "NumberHub" +versionCode = "5" +versionName = "0.5.0" androidxBrowserBrowser = "1.8.0" androidGradlePlugin = "8.3.2" From a25e773f835753544a22746f6ee0301a823dd8ff Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Fri, 19 Jul 2024 19:50:37 +0200 Subject: [PATCH 17/27] chore: Fix fastlane Signed-off-by: Myzel394 <50424412+Myzel394@users.noreply.github.com> --- .../android/en-US/full_description.txt | 30 +++++++------------ fastlane/metadata/android/en-US/title.txt | 2 +- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index a42642b4..3ac42b2d 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -1,33 +1,25 @@ -Calculator, converter and more. +Calculator, converter and so much more! -Look for Calculator on your home screen after installing the app. +NumberHub will be installed as "Calculator" on your home screen. -• Deep customization: themes, number formatter and etc. -• No ads, in-app purchases or asking for donations +• No ads or in-app purchases • Open source -Calculator +Calculator • Copy, paste, save and share expression results • Trigonometric functions • Fractional output -Unit converter +Unit converter -• 570 units -• Built-in currency converter -• Favorite units -• Organize unit groups -• Smart search algorithm +Over 500 units! Convert miles to kilometers, Dollar to Euro, Bytes to Gigabytes and so much more! -Date calculator -• Add and subtract dates -• Calculate difference -• Create events in calendar +Date calculator +Add and subtract dates with ease -Time converter -• Add to favorites -• Add labels to time zones +Time converter +Convert time zones The app uses https://github.com/fawazahmed0/currency-api by https://github.com/fawazahmed0 -Requests are send to cdn.jsdelivr.net. +Requests are sent to cdn.jsdelivr.net. diff --git a/fastlane/metadata/android/en-US/title.txt b/fastlane/metadata/android/en-US/title.txt index 6d900611..1badc77f 100644 --- a/fastlane/metadata/android/en-US/title.txt +++ b/fastlane/metadata/android/en-US/title.txt @@ -1 +1 @@ -Unitto — calculator and unit converter \ No newline at end of file +NumberHub \ No newline at end of file From cbf3fa54f8bad389ad1f275b826be7e690a3dcb0 Mon Sep 17 00:00:00 2001 From: Crazy Unicorn <30509883+Crazy-Unicooorn@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:45:26 +0000 Subject: [PATCH 18/27] updated french translations --- core/base/src/main/res/values-fr/strings.xml | 360 +++++++++---------- 1 file changed, 180 insertions(+), 180 deletions(-) diff --git a/core/base/src/main/res/values-fr/strings.xml b/core/base/src/main/res/values-fr/strings.xml index 436b4d4e..59574480 100644 --- a/core/base/src/main/res/values-fr/strings.xml +++ b/core/base/src/main/res/values-fr/strings.xml @@ -26,7 +26,7 @@ Filtre vérifié Vider l\'historique Effacer l\'entrée - Clear + Effacer Cliquez pour réessayer Virgule Ajouter ou supprimer une unité des favoris @@ -61,7 +61,7 @@ Ouvrir ou fermer le menu déroulant Activé Erreur - Bonjour! + Bonjour ! Chargement… Naviguer vers le haut @@ -78,16 +78,16 @@ Used in this dialog window. Should be short --> Choisir le temps - À propos d\'NumberHub + À propos de NumberHub En savoir plus sur l\'application - Additional + Supplémentaires AMOLED Noir Utiliser un fond noir pour les thèmes sombres Auto Vue historique Effacer le cache Palette de couleurs - Thème couleur + Couleurs du thème Choisir un mode de thème Groupes d\'unités, tri, formatage Les taux de change sont mis à jour quotidiennement. L\'application ne permet pas de suivre le marché en temps réel. @@ -101,9 +101,9 @@ Used in this dialog window. Should be short --> Activer le groupe d\'unités Notation exponentielle Remplacer une partie du nombre par E - Formatter l\'heure + Formater l\'heure Exemple : Afficher 130 minutes comme 2h 10m - Formattage + Formatage Aperçu (cliquez pour changer)