mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-18 16:25:27 +02:00
Bumpy bumps
Updated navigation logic
This commit is contained in:
parent
eb9b12da28
commit
7c70258b84
@ -28,12 +28,12 @@ plugins {
|
||||
|
||||
android {
|
||||
namespace = "com.sadellie.unitto"
|
||||
compileSdk = 33
|
||||
compileSdk = 34
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.sadellie.unitto"
|
||||
minSdk = 21
|
||||
targetSdk = 33
|
||||
targetSdk = 34
|
||||
versionCode = 22
|
||||
versionName = "Lilac Luster"
|
||||
}
|
||||
|
@ -19,10 +19,8 @@
|
||||
package com.sadellie.unitto
|
||||
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.material3.DrawerValue
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalNavigationDrawer
|
||||
import androidx.compose.material3.rememberDrawerState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
@ -40,6 +38,10 @@ import androidx.navigation.compose.rememberNavController
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||
import com.sadellie.unitto.core.ui.common.UnittoDrawerSheet
|
||||
import com.sadellie.unitto.core.ui.common.UnittoModalNavigationDrawer
|
||||
import com.sadellie.unitto.core.ui.common.close
|
||||
import com.sadellie.unitto.core.ui.common.open
|
||||
import com.sadellie.unitto.core.ui.common.rememberUnittoDrawerState
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItems
|
||||
import com.sadellie.unitto.core.ui.theme.AppTypography
|
||||
import com.sadellie.unitto.core.ui.theme.DarkThemeColors
|
||||
@ -49,13 +51,13 @@ import io.github.sadellie.themmo.Themmo
|
||||
import io.github.sadellie.themmo.rememberThemmoController
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
internal fun UnittoApp(uiPrefs: UIPreferences) {
|
||||
|
||||
val themmoController = rememberThemmoController(
|
||||
lightColorScheme = LightThemeColors,
|
||||
darkColorScheme = DarkThemeColors,
|
||||
// Anything below will not be called if theming mode is still loading from DataStore
|
||||
themingMode = uiPrefs.themingMode,
|
||||
dynamicThemeEnabled = uiPrefs.enableDynamicTheme,
|
||||
amoledThemeEnabled = uiPrefs.enableAmoledTheme,
|
||||
@ -66,7 +68,7 @@ internal fun UnittoApp(uiPrefs: UIPreferences) {
|
||||
val sysUiController = rememberSystemUiController()
|
||||
|
||||
// Navigation drawer stuff
|
||||
val drawerState = rememberDrawerState(DrawerValue.Closed)
|
||||
val drawerState = rememberUnittoDrawerState()
|
||||
val drawerScope = rememberCoroutineScope()
|
||||
val mainTabs = listOf(
|
||||
DrawerItems.Calculator,
|
||||
@ -88,14 +90,6 @@ internal fun UnittoApp(uiPrefs: UIPreferences) {
|
||||
}
|
||||
}
|
||||
}
|
||||
val gesturesEnabled: Boolean by remember(navBackStackEntry?.destination) {
|
||||
derivedStateOf {
|
||||
// Will be true for routes like
|
||||
// [null, calculator_route, settings_graph, settings_route, themes_route]
|
||||
// We disable drawer drag gesture when we are too deep
|
||||
navController.backQueue.size <= 4
|
||||
}
|
||||
}
|
||||
|
||||
Themmo(
|
||||
themmoController = themmoController,
|
||||
@ -107,10 +101,8 @@ internal fun UnittoApp(uiPrefs: UIPreferences) {
|
||||
mutableStateOf(backgroundColor.luminance() > 0.5f)
|
||||
}
|
||||
|
||||
ModalNavigationDrawer(
|
||||
drawerState = drawerState,
|
||||
gesturesEnabled = gesturesEnabled,
|
||||
drawerContent = {
|
||||
UnittoModalNavigationDrawer(
|
||||
drawer = {
|
||||
UnittoDrawerSheet(
|
||||
modifier = Modifier,
|
||||
mainTabs = mainTabs,
|
||||
@ -126,15 +118,20 @@ internal fun UnittoApp(uiPrefs: UIPreferences) {
|
||||
restoreState = true
|
||||
}
|
||||
}
|
||||
},
|
||||
modifier = Modifier,
|
||||
state = drawerState,
|
||||
gesturesEnabled = true,
|
||||
scope = drawerScope,
|
||||
content = {
|
||||
UnittoNavigation(
|
||||
navController = navController,
|
||||
themmoController = it,
|
||||
startDestination = uiPrefs.startingScreen,
|
||||
openDrawer = { drawerScope.launch { drawerState.open() } }
|
||||
)
|
||||
}
|
||||
) {
|
||||
UnittoNavigation(
|
||||
navController = navController,
|
||||
themmoController = it,
|
||||
startDestination = uiPrefs.startingScreen,
|
||||
openDrawer = { drawerScope.launch { drawerState.open() } }
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
LaunchedEffect(useDarkIcons) {
|
||||
sysUiController.setNavigationBarColor(Color.Transparent, useDarkIcons)
|
||||
|
@ -23,7 +23,6 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import com.sadellie.unitto.feature.calculator.navigation.calculatorScreen
|
||||
@ -55,20 +54,10 @@ internal fun UnittoNavigation(
|
||||
startDestination = startDestination,
|
||||
modifier = Modifier.background(MaterialTheme.colorScheme.background)
|
||||
) {
|
||||
fun navigateToSettings() {
|
||||
navController.navigateToSettings {
|
||||
popUpTo(navController.graph.findStartDestination().id) {
|
||||
saveState = true
|
||||
}
|
||||
launchSingleTop = true
|
||||
restoreState = true
|
||||
}
|
||||
}
|
||||
|
||||
converterScreen(
|
||||
navigateToLeftScreen = navController::navigateToLeftSide,
|
||||
navigateToRightScreen = navController::navigateToRightSide,
|
||||
navigateToSettings = ::navigateToSettings,
|
||||
navigateToSettings = navController::navigateToSettings,
|
||||
navigateToMenu = openDrawer,
|
||||
viewModel = converterViewModel
|
||||
)
|
||||
@ -95,12 +84,12 @@ internal fun UnittoNavigation(
|
||||
|
||||
calculatorScreen(
|
||||
navigateToMenu = openDrawer,
|
||||
navigateToSettings = ::navigateToSettings
|
||||
navigateToSettings = navController::navigateToSettings
|
||||
)
|
||||
|
||||
dateDifferenceScreen(
|
||||
navigateToMenu = openDrawer,
|
||||
navigateToSettings = ::navigateToSettings
|
||||
navigateToSettings = navController::navigateToSettings
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import org.gradle.api.artifacts.VersionCatalogsExtension
|
||||
import org.gradle.kotlin.dsl.dependencies
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
|
||||
@Suppress("UNUSED")
|
||||
class UnittoHiltPlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) {
|
||||
with(target) {
|
||||
|
@ -25,6 +25,7 @@ import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.dependencies
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
|
||||
@Suppress("UNUSED")
|
||||
class UnittoLibraryComposePlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) {
|
||||
with(target) {
|
||||
|
@ -22,6 +22,7 @@ import org.gradle.api.artifacts.VersionCatalogsExtension
|
||||
import org.gradle.kotlin.dsl.dependencies
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
|
||||
@Suppress("UNUSED")
|
||||
class UnittoLibraryFeaturePlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) {
|
||||
with(target) {
|
||||
|
@ -25,6 +25,7 @@ import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.dependencies
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
|
||||
@Suppress("UNUSED")
|
||||
class UnittoLibraryPlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) {
|
||||
with(target) {
|
||||
|
@ -34,7 +34,7 @@ internal fun Project.configureKotlinAndroid(
|
||||
commonExtension: CommonExtension<*, *, *, *>,
|
||||
) {
|
||||
commonExtension.apply {
|
||||
compileSdk = 33
|
||||
compileSdk = 34
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 21
|
||||
|
@ -37,7 +37,6 @@ android {
|
||||
|
||||
dependencies {
|
||||
testImplementation(libs.junit)
|
||||
testImplementation(libs.org.robolectric)
|
||||
testImplementation(libs.androidx.compose.ui.test.junit4)
|
||||
debugImplementation(libs.androidx.compose.ui.test.manifest)
|
||||
|
||||
|
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Unitto is a unit converter for Android
|
||||
* Copyright (c) 2023 Elshan Agaev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sadellie.unitto.core.ui.common
|
||||
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.Canvas
|
||||
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.gestures.animateTo
|
||||
import androidx.compose.foundation.gestures.detectTapGestures
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.DrawerDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItems
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
// Why do I have to do it myself?
|
||||
@Composable
|
||||
fun UnittoModalNavigationDrawer(
|
||||
drawer: @Composable () -> Unit,
|
||||
modifier: Modifier,
|
||||
state: AnchoredDraggableState<UnittoDrawerState>,
|
||||
gesturesEnabled: Boolean,
|
||||
scope: CoroutineScope,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
Box(modifier.fillMaxSize()) {
|
||||
content()
|
||||
|
||||
Scrim(
|
||||
open = state.isOpen,
|
||||
onClose = { if (gesturesEnabled) scope.launch { state.close() } },
|
||||
fraction = {
|
||||
fraction(state.anchors.minAnchor(), state.anchors.maxAnchor(), state.offset)
|
||||
},
|
||||
color = DrawerDefaults.scrimColor
|
||||
)
|
||||
|
||||
// Drawer
|
||||
Box(Modifier
|
||||
.offset {
|
||||
IntOffset(
|
||||
x = state
|
||||
.requireOffset()
|
||||
.roundToInt(), y = 0
|
||||
)
|
||||
}
|
||||
.anchoredDraggable(
|
||||
state = state,
|
||||
orientation = Orientation.Horizontal,
|
||||
enabled = gesturesEnabled or state.isOpen,
|
||||
)
|
||||
.padding(end = 18.dp) // Draggable when closed
|
||||
) {
|
||||
drawer()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Scrim(
|
||||
open: Boolean,
|
||||
onClose: () -> Unit,
|
||||
fraction: () -> Float,
|
||||
color: Color,
|
||||
) {
|
||||
val dismissDrawer = if (open) {
|
||||
Modifier.pointerInput(onClose) { detectTapGestures { onClose() } }
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
|
||||
Canvas(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.then(dismissDrawer)
|
||||
) {
|
||||
drawRect(color, alpha = fraction())
|
||||
}
|
||||
}
|
||||
|
||||
enum class UnittoDrawerState { OPEN, CLOSED }
|
||||
|
||||
@Composable
|
||||
fun rememberUnittoDrawerState(
|
||||
initialValue: UnittoDrawerState = UnittoDrawerState.CLOSED,
|
||||
): AnchoredDraggableState<UnittoDrawerState> {
|
||||
val minValue = -with(LocalDensity.current) { 360.dp.toPx() }
|
||||
val positionalThreshold = -minValue * 0.5f
|
||||
val velocityThreshold = with(LocalDensity.current) { 400.dp.toPx() }
|
||||
|
||||
return remember {
|
||||
AnchoredDraggableState(
|
||||
initialValue = initialValue,
|
||||
anchors = DraggableAnchors {
|
||||
UnittoDrawerState.OPEN at 0F
|
||||
UnittoDrawerState.CLOSED at minValue
|
||||
},
|
||||
positionalThreshold = { positionalThreshold },
|
||||
velocityThreshold = { velocityThreshold },
|
||||
animationSpec = tween()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private val AnchoredDraggableState<UnittoDrawerState>.isOpen
|
||||
get() = this.currentValue == UnittoDrawerState.OPEN
|
||||
|
||||
suspend fun AnchoredDraggableState<UnittoDrawerState>.close() {
|
||||
this.animateTo(UnittoDrawerState.CLOSED)
|
||||
}
|
||||
|
||||
suspend fun AnchoredDraggableState<UnittoDrawerState>.open() {
|
||||
this.animateTo(UnittoDrawerState.OPEN)
|
||||
}
|
||||
|
||||
private fun fraction(a: Float, b: Float, pos: Float) =
|
||||
((pos - a) / (b - a)).coerceIn(0f, 1f)
|
||||
|
||||
@Preview(backgroundColor = 0xFFC8F7D4, showBackground = true, showSystemUi = true)
|
||||
@Composable
|
||||
private fun PreviewUnittoModalNavigationDrawer() {
|
||||
val drawerState = rememberUnittoDrawerState(initialValue = UnittoDrawerState.OPEN)
|
||||
val corScope = rememberCoroutineScope()
|
||||
|
||||
UnittoModalNavigationDrawer(
|
||||
drawer = {
|
||||
UnittoDrawerSheet(
|
||||
modifier = Modifier,
|
||||
mainTabs = listOf(
|
||||
DrawerItems.Calculator,
|
||||
DrawerItems.Calculator,
|
||||
DrawerItems.Calculator,
|
||||
),
|
||||
additionalTabs = listOf(
|
||||
DrawerItems.Calculator,
|
||||
DrawerItems.Calculator,
|
||||
DrawerItems.Calculator,
|
||||
),
|
||||
currentDestination = DrawerItems.Calculator.destination,
|
||||
onItemClick = {}
|
||||
)
|
||||
},
|
||||
modifier = Modifier,
|
||||
state = drawerState,
|
||||
gesturesEnabled = true,
|
||||
scope = corScope,
|
||||
content = {
|
||||
Column {
|
||||
Text(text = "Content")
|
||||
Button(
|
||||
onClick = { corScope.launch { drawerState.open() } }
|
||||
) {
|
||||
Text(text = "BUTTON")
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
@ -26,11 +26,11 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Slider
|
||||
import androidx.compose.material3.SliderPositions
|
||||
import androidx.compose.material3.SliderState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.mutableFloatStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
@ -72,18 +72,18 @@ fun UnittoSlider(
|
||||
|
||||
@Composable
|
||||
private fun SquigglyTrack(
|
||||
sliderPosition: SliderPositions,
|
||||
sliderState: SliderState,
|
||||
eachWaveWidth: Float = 80f,
|
||||
strokeWidth: Float = 15f,
|
||||
filledColor: Color = MaterialTheme.colorScheme.primary,
|
||||
unfilledColor: Color = MaterialTheme.colorScheme.surfaceVariant
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
var direct by remember { mutableStateOf(0.72f) }
|
||||
var direct by remember { mutableFloatStateOf(0.72f) }
|
||||
val animatedDirect = animateFloatAsState(direct, spring(stiffness = Spring.StiffnessLow))
|
||||
val slider = sliderPosition.activeRange.endInclusive
|
||||
val slider = sliderState.valueRange.endInclusive
|
||||
|
||||
LaunchedEffect(sliderPosition.activeRange.endInclusive) {
|
||||
LaunchedEffect(sliderState.valueRange.endInclusive) {
|
||||
coroutineScope.launch {
|
||||
delay(200L)
|
||||
direct *= -1
|
||||
@ -148,7 +148,7 @@ private fun SquigglyTrack(
|
||||
@Preview(device = "spec:width=1920dp,height=1080dp,dpi=480")
|
||||
@Composable
|
||||
private fun PreviewNewSlider() {
|
||||
var currentValue by remember { mutableStateOf(0.9f) }
|
||||
var currentValue by remember { mutableFloatStateOf(0.9f) }
|
||||
|
||||
UnittoSlider(
|
||||
value = currentValue,
|
||||
|
@ -20,8 +20,8 @@ package com.sadellie.unitto.core.ui
|
||||
|
||||
import com.sadellie.unitto.core.ui.common.textfield.ExpressionTransformer
|
||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ExpressionTransformerTest {
|
||||
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
package com.sadellie.unitto.data.common
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
|
||||
class IsExpressionText {
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
package com.sadellie.unitto.data.epoch
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class DateToEpochTest {
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
package io.github.sadellie.evaluatto
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ExpressionComplexTest {
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
package io.github.sadellie.evaluatto
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ExpressionExceptionsTest {
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
package io.github.sadellie.evaluatto
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ExpressionSimpleTest {
|
||||
|
||||
|
@ -18,9 +18,10 @@
|
||||
|
||||
package io.github.sadellie.evaluatto
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class FixLexiconTest {
|
||||
|
||||
@Test
|
||||
fun `missing multiply`() {
|
||||
assertLex(
|
||||
|
@ -18,12 +18,13 @@
|
||||
|
||||
package io.github.sadellie.evaluatto
|
||||
|
||||
import org.junit.Assert
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
|
||||
fun assertExpr(expr: String, result: String, radianMode: Boolean = true) =
|
||||
Assert.assertEquals(
|
||||
assertEquals(
|
||||
BigDecimal(result).setScale(10, RoundingMode.HALF_EVEN),
|
||||
Expression(expr, radianMode).calculate().setScale(10, RoundingMode.HALF_EVEN)
|
||||
)
|
||||
@ -33,13 +34,13 @@ fun <T : Throwable?> assertExprFail(
|
||||
expr: String,
|
||||
radianMode: Boolean = true
|
||||
) {
|
||||
Assert.assertThrows(expectedThrowable) {
|
||||
assertThrows(expectedThrowable) {
|
||||
Expression(expr, radianMode = radianMode).calculate()
|
||||
}
|
||||
}
|
||||
|
||||
fun assertLex(expected: List<String>, actual: String) =
|
||||
Assert.assertEquals(expected, Tokenizer(actual).tokenize())
|
||||
assertEquals(expected, Tokenizer(actual).tokenize())
|
||||
|
||||
fun assertLex(expected: String, actual: String) =
|
||||
Assert.assertEquals(expected, Tokenizer(actual).tokenize().joinToString(""))
|
||||
assertEquals(expected, Tokenizer(actual).tokenize().joinToString(""))
|
||||
|
@ -18,9 +18,10 @@
|
||||
|
||||
package io.github.sadellie.evaluatto
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class TokenizerTest {
|
||||
|
||||
@Test
|
||||
fun tokens1() = assertLex(listOf("789"), "789")
|
||||
|
||||
|
@ -21,8 +21,8 @@ package com.sadellie.unitto.data.units
|
||||
import com.sadellie.unitto.data.model.ALL_UNIT_GROUPS
|
||||
import com.sadellie.unitto.data.model.AbstractUnit
|
||||
import com.sadellie.unitto.data.model.UnitGroup
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.math.BigDecimal
|
||||
|
||||
class AllUnitsRepositoryTest {
|
||||
|
@ -20,14 +20,11 @@ package com.sadellie.unitto.data.units
|
||||
|
||||
import com.sadellie.unitto.data.model.NumberBaseUnit
|
||||
import com.sadellie.unitto.data.model.UnitGroup
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.math.BigDecimal
|
||||
|
||||
@RunWith(JUnit4::class)
|
||||
class AllUnitsTest {
|
||||
|
||||
// Group and it's tested unit ids
|
||||
@ -527,7 +524,7 @@ class AllUnitsTest {
|
||||
history[unitFrom.group] = content.plus(this)
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
fun after() {
|
||||
val unitGroup = history.keys.first()
|
||||
// GROUP : testedCount / totalCount
|
||||
|
@ -22,8 +22,8 @@ import com.sadellie.unitto.data.model.AbstractUnit
|
||||
import com.sadellie.unitto.data.model.DefaultUnit
|
||||
import com.sadellie.unitto.data.model.UnitGroup
|
||||
import com.sadellie.unitto.data.model.sortByLev
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.math.BigDecimal
|
||||
|
||||
val baseList: List<AbstractUnit> = listOf(
|
||||
|
@ -19,8 +19,8 @@
|
||||
package com.sadellie.unitto.data.units
|
||||
|
||||
import com.sadellie.unitto.data.common.lev
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class LevenshteinTest {
|
||||
|
||||
|
@ -19,8 +19,8 @@
|
||||
package com.sadellie.unitto.data.units
|
||||
|
||||
import com.sadellie.unitto.data.common.setMinimumRequiredScale
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.math.BigDecimal
|
||||
|
||||
class MinimumRequiredScaleTest {
|
||||
|
@ -47,6 +47,7 @@ import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
@ -120,8 +121,8 @@ private fun CalculatorScreen(
|
||||
val dragCoroutineScope = rememberCoroutineScope()
|
||||
val dragAnimSpec = rememberSplineBasedDecay<Float>()
|
||||
|
||||
var textThingyHeight by remember { mutableStateOf(0) }
|
||||
var historyItemHeight by remember { mutableStateOf(0) }
|
||||
var textThingyHeight by remember { mutableIntStateOf(0) }
|
||||
var historyItemHeight by remember { mutableIntStateOf(0) }
|
||||
|
||||
var showClearHistoryDialog by rememberSaveable { mutableStateOf(false) }
|
||||
val showClearHistoryButton by remember(dragAmount.value, historyItemHeight) {
|
||||
|
@ -30,7 +30,6 @@ android {
|
||||
dependencies {
|
||||
testImplementation(libs.junit)
|
||||
testImplementation(libs.org.jetbrains.kotlinx.coroutines.test)
|
||||
testImplementation(libs.org.robolectric)
|
||||
testImplementation(libs.androidx.room.runtime)
|
||||
testImplementation(libs.androidx.room.ktx)
|
||||
kapt(libs.androidx.room.compiler)
|
||||
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Unitto is a unit converter for Android
|
||||
* Copyright (c) 2022-2023 Elshan Agaev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sadellie.unitto.feature.converter
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.TestDispatcher
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.resetMain
|
||||
import kotlinx.coroutines.test.setMain
|
||||
import org.junit.rules.TestWatcher
|
||||
import org.junit.runner.Description
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
class CoroutineTestRule(private val dispatcher: TestDispatcher = UnconfinedTestDispatcher()) :
|
||||
TestWatcher() {
|
||||
|
||||
override fun starting(description: Description) {
|
||||
super.starting(description)
|
||||
Dispatchers.setMain(dispatcher)
|
||||
}
|
||||
|
||||
override fun finished(description: Description) {
|
||||
super.finished(description)
|
||||
Dispatchers.resetMain()
|
||||
}
|
||||
|
||||
}
|
@ -18,8 +18,8 @@
|
||||
|
||||
package com.sadellie.unitto.feature.datedifference
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
|
@ -37,6 +37,7 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
@ -59,7 +60,7 @@ internal fun AboutScreen(
|
||||
) {
|
||||
val mContext = LocalContext.current
|
||||
val userPrefs = viewModel.userPrefs.collectAsStateWithLifecycle()
|
||||
var aboutItemClick: Int by rememberSaveable { mutableStateOf(0) }
|
||||
var aboutItemClick: Int by rememberSaveable { mutableIntStateOf(0) }
|
||||
var showDialog: Boolean by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
UnittoScreenWithLargeTopBar(
|
||||
|
@ -40,7 +40,7 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -56,10 +56,10 @@ import com.sadellie.unitto.core.base.OutputFormat
|
||||
import com.sadellie.unitto.core.base.R
|
||||
import com.sadellie.unitto.core.base.Separator
|
||||
import com.sadellie.unitto.core.ui.common.NavigateUpButton
|
||||
import com.sadellie.unitto.core.ui.common.UnittoSlider
|
||||
import com.sadellie.unitto.core.ui.common.SegmentedButton
|
||||
import com.sadellie.unitto.core.ui.common.SegmentedButtonsRow
|
||||
import com.sadellie.unitto.core.ui.common.UnittoScreenWithLargeTopBar
|
||||
import com.sadellie.unitto.core.ui.common.UnittoSlider
|
||||
import com.sadellie.unitto.core.ui.common.squashable
|
||||
import com.sadellie.unitto.core.ui.common.textfield.formatExpression
|
||||
import com.sadellie.unitto.core.ui.theme.NumbersTextStyleDisplayMedium
|
||||
@ -255,9 +255,9 @@ fun FormattingScreen(
|
||||
@Preview
|
||||
@Composable
|
||||
private fun PreviewFormattingScreen() {
|
||||
var currentPrecision by remember { mutableStateOf(6) }
|
||||
var currentSeparator by remember { mutableStateOf(Separator.COMMA) }
|
||||
var currentOutputFormat by remember { mutableStateOf(OutputFormat.PLAIN) }
|
||||
var currentPrecision by remember { mutableIntStateOf(6) }
|
||||
var currentSeparator by remember { mutableIntStateOf(Separator.COMMA) }
|
||||
var currentOutputFormat by remember { mutableIntStateOf(OutputFormat.PLAIN) }
|
||||
|
||||
FormattingScreen(
|
||||
uiState = FormattingUIState(
|
||||
|
@ -21,7 +21,6 @@ package com.sadellie.unitto.feature.settings.navigation
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavOptionsBuilder
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.navigation
|
||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||
@ -41,8 +40,8 @@ internal const val thirdPartyRoute = "third_party_route"
|
||||
internal const val aboutRoute = "about_route"
|
||||
internal const val formattingRoute = "formatting_route"
|
||||
|
||||
fun NavController.navigateToSettings(builder: NavOptionsBuilder.() -> Unit) {
|
||||
navigate(settingsRoute, builder)
|
||||
fun NavController.navigateToSettings() {
|
||||
navigate(settingsRoute)
|
||||
}
|
||||
|
||||
fun NavController.navigateToUnitGroups() {
|
||||
|
@ -1,39 +1,39 @@
|
||||
[versions]
|
||||
appCode = "22"
|
||||
appName = "Lilac Luster"
|
||||
kotlin = "1.8.21"
|
||||
androidxCore = "1.10.0"
|
||||
androidGradlePlugin = "8.0.1"
|
||||
orgJetbrainsKotlinxCoroutinesTest = "1.6.4"
|
||||
kotlin = "1.9.0"
|
||||
androidxCore = "1.10.1"
|
||||
androidGradlePlugin = "8.0.2"
|
||||
orgJetbrainsKotlinxCoroutinesTest = "1.7.2"
|
||||
androidxCompose = "1.5.0-alpha02"
|
||||
androidxComposeCompiler = "1.4.7"
|
||||
androidxComposeUi = "1.5.0-alpha04"
|
||||
androidxComposeMaterial3 = "1.2.0-alpha01"
|
||||
androidxNavigation = "2.5.3"
|
||||
androidxComposeCompiler = "1.5.0"
|
||||
androidxComposeUi = "1.6.0-alpha01"
|
||||
androidxComposeMaterial3 = "1.2.0-alpha03"
|
||||
androidxNavigation = "2.6.0"
|
||||
androidxLifecycleRuntimeCompose = "2.6.1"
|
||||
androidxHilt = "1.0.0"
|
||||
comGoogleDagger = "2.45"
|
||||
androidxComposeMaterialIconsExtended = "1.5.0-alpha04"
|
||||
comGoogleDagger = "2.47"
|
||||
androidxComposeMaterialIconsExtended = "1.6.0-alpha01"
|
||||
androidxDatastore = "1.0.0"
|
||||
comGoogleAccompanist = "0.30.1"
|
||||
androidxRoom = "2.5.1"
|
||||
comSquareupMoshi = "1.14.0"
|
||||
androidxRoom = "2.6.0-alpha02"
|
||||
comSquareupMoshi = "1.15.0"
|
||||
comSquareupRetrofit2 = "2.9.0"
|
||||
comGithubSadellieThemmo = "ed4063f70f"
|
||||
comGithubSadellieThemmo = "1.0.0"
|
||||
orgBurnoutcrewComposereorderable = "0.9.6"
|
||||
junit = "4.13.2"
|
||||
junit = "5.9.3"
|
||||
androidxTest = "1.5.0"
|
||||
androidxTestExt = "1.1.4"
|
||||
androidxTestExt = "1.1.5"
|
||||
androidDesugarJdkLibs = "2.0.3"
|
||||
androidxTestRunner = "1.5.1"
|
||||
androidxTestRunner = "1.5.2"
|
||||
androidxTestRules = "1.5.0"
|
||||
orgRobolectric = "4.9"
|
||||
orgRobolectric = "4.10.3"
|
||||
|
||||
[libraries]
|
||||
androidx-core = { group = "androidx.core", name = "core-ktx", version.ref = "androidxCore" }
|
||||
androidx-test = { group = "androidx.test", name = "core", version.ref = "androidxTest" }
|
||||
androidx-test-ext = { group = "androidx.test.ext", name = "junit-ktx", version.ref = "androidxTestExt" }
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
junit = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junit" }
|
||||
androidx-test-runner = { group = "androidx.test", name = "runner", version.ref = "androidxTestRunner" }
|
||||
androidx-test-rules = { group = "androidx.test", name = "rules", version.ref = "androidxTestRules" }
|
||||
org-robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "orgRobolectric" }
|
||||
|
Loading…
x
Reference in New Issue
Block a user