mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-19 08:45:27 +02:00
Loading state for Unit Converter and Calculator keyboards
This commit is contained in:
parent
2405a2656a
commit
1d5bbaf5b2
@ -70,6 +70,7 @@ import com.sadellie.unitto.core.ui.common.textfield.ExpressionTextField
|
||||
import com.sadellie.unitto.core.ui.common.textfield.UnformattedTextField
|
||||
import com.sadellie.unitto.data.model.HistoryItem
|
||||
import com.sadellie.unitto.feature.calculator.components.CalculatorKeyboard
|
||||
import com.sadellie.unitto.feature.calculator.components.CalculatorKeyboardLoading
|
||||
import com.sadellie.unitto.feature.calculator.components.HistoryList
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
@ -80,10 +81,15 @@ internal fun CalculatorRoute(
|
||||
navigateToSettings: () -> Unit,
|
||||
viewModel: CalculatorViewModel = hiltViewModel()
|
||||
) {
|
||||
val uiState = viewModel.uiState.collectAsStateWithLifecycle()
|
||||
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
|
||||
|
||||
CalculatorScreen(
|
||||
uiState = uiState.value,
|
||||
when (uiState) {
|
||||
is CalculatorUIState.Loading -> Loading(
|
||||
navigateToMenu = navigateToMenu,
|
||||
navigateToSettings = navigateToSettings,
|
||||
)
|
||||
is CalculatorUIState.Ready -> CalculatorScreen(
|
||||
uiState = uiState,
|
||||
navigateToMenu = navigateToMenu,
|
||||
navigateToSettings = navigateToSettings,
|
||||
addSymbol = viewModel::addTokens,
|
||||
@ -94,11 +100,12 @@ internal fun CalculatorRoute(
|
||||
evaluate = viewModel::evaluate,
|
||||
clearHistory = viewModel::clearHistory
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun CalculatorScreen(
|
||||
uiState: CalculatorUIState,
|
||||
uiState: CalculatorUIState.Ready,
|
||||
navigateToMenu: () -> Unit,
|
||||
navigateToSettings: () -> Unit,
|
||||
addSymbol: (String) -> Unit,
|
||||
@ -317,6 +324,80 @@ private fun CalculatorScreen(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Loading(
|
||||
navigateToMenu: () -> Unit,
|
||||
navigateToSettings: () -> Unit,
|
||||
) {
|
||||
UnittoScreenWithTopBar(
|
||||
title = { Text(stringResource(R.string.calculator)) },
|
||||
navigationIcon = { MenuButton { navigateToMenu() } },
|
||||
colors = TopAppBarDefaults.topAppBarColors(MaterialTheme.colorScheme.surfaceVariant),
|
||||
actions = { SettingsButton(navigateToSettings) }
|
||||
) { paddingValues ->
|
||||
BoxWithConstraints(
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
) {
|
||||
// Input
|
||||
Column(
|
||||
Modifier
|
||||
.height(maxHeight * 0.25f)
|
||||
.background(
|
||||
MaterialTheme.colorScheme.surfaceVariant,
|
||||
RoundedCornerShape(
|
||||
topStartPercent = 0, topEndPercent = 0,
|
||||
bottomStartPercent = 20, bottomEndPercent = 20
|
||||
)
|
||||
)
|
||||
.padding(top = 12.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
UnformattedTextField(
|
||||
modifier = Modifier
|
||||
.weight(2f)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp),
|
||||
value = TextFieldValue(),
|
||||
minRatio = 0.5f,
|
||||
onCursorChange = {},
|
||||
)
|
||||
if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
UnformattedTextField(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp),
|
||||
value = TextFieldValue(),
|
||||
minRatio = 1f,
|
||||
onCursorChange = {},
|
||||
readOnly = true,
|
||||
)
|
||||
}
|
||||
// Handle
|
||||
Box(
|
||||
Modifier
|
||||
.padding(8.dp)
|
||||
.background(
|
||||
MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
RoundedCornerShape(100)
|
||||
)
|
||||
.sizeIn(24.dp, 4.dp)
|
||||
)
|
||||
}
|
||||
|
||||
// Keyboard
|
||||
CalculatorKeyboardLoading(
|
||||
modifier = Modifier
|
||||
.offset(y = maxHeight * 0.25f)
|
||||
.height(maxHeight * 0.75f)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp, vertical = 4.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 432, heightDp = 1008, device = "spec:parent=pixel_5,orientation=portrait")
|
||||
@Preview(widthDp = 432, heightDp = 864, device = "spec:parent=pixel_5,orientation=portrait")
|
||||
@Preview(widthDp = 597, heightDp = 1393, device = "spec:parent=pixel_5,orientation=portrait")
|
||||
@ -346,7 +427,7 @@ private fun PreviewCalculatorScreen() {
|
||||
}
|
||||
|
||||
CalculatorScreen(
|
||||
uiState = CalculatorUIState(
|
||||
uiState = CalculatorUIState.Ready(
|
||||
input = TextFieldValue("1.2345"),
|
||||
output = CalculationResult.Default("1234"),
|
||||
history = historyItems
|
||||
|
@ -24,7 +24,10 @@ import com.sadellie.unitto.core.base.R
|
||||
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
|
||||
import com.sadellie.unitto.data.model.HistoryItem
|
||||
|
||||
data class CalculatorUIState(
|
||||
internal sealed class CalculatorUIState {
|
||||
data object Loading : CalculatorUIState()
|
||||
|
||||
data class Ready(
|
||||
val input: TextFieldValue = TextFieldValue(),
|
||||
val output: CalculationResult = CalculationResult.Default(),
|
||||
val radianMode: Boolean = true,
|
||||
@ -32,7 +35,8 @@ data class CalculatorUIState(
|
||||
val allowVibration: Boolean = false,
|
||||
val formatterSymbols: FormatterSymbols = FormatterSymbols.Spaces,
|
||||
val middleZero: Boolean = false,
|
||||
)
|
||||
) : CalculatorUIState()
|
||||
}
|
||||
|
||||
sealed class CalculationResult(@StringRes val label: Int? = null) {
|
||||
data class Default(val text: String = "") : CalculationResult()
|
||||
|
@ -69,7 +69,7 @@ internal class CalculatorViewModel @Inject constructor(
|
||||
val uiState = combine(
|
||||
_input, _output, _history, _userPrefs
|
||||
) { input, output, history, userPrefs ->
|
||||
return@combine CalculatorUIState(
|
||||
return@combine CalculatorUIState.Ready(
|
||||
input = input,
|
||||
output = output,
|
||||
radianMode = userPrefs.radianMode,
|
||||
@ -79,7 +79,7 @@ internal class CalculatorViewModel @Inject constructor(
|
||||
middleZero = userPrefs.middleZero,
|
||||
)
|
||||
}.stateIn(
|
||||
viewModelScope, SharingStarted.WhileSubscribed(5000L), CalculatorUIState()
|
||||
viewModelScope, SharingStarted.WhileSubscribed(5000L), CalculatorUIState.Loading
|
||||
)
|
||||
|
||||
fun addTokens(tokens: String) = _input.update { it.addTokens(tokens) }
|
||||
|
@ -24,6 +24,7 @@ import androidx.compose.animation.Crossfade
|
||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@ -34,6 +35,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ExpandLess
|
||||
import androidx.compose.material3.Icon
|
||||
@ -48,9 +50,11 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.sadellie.unitto.core.base.Token
|
||||
import com.sadellie.unitto.core.ui.common.ColumnWithConstraints
|
||||
import com.sadellie.unitto.core.ui.common.KeyboardButtonAdditional
|
||||
@ -140,6 +144,118 @@ internal fun CalculatorKeyboard(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun CalculatorKeyboardLoading(
|
||||
modifier: Modifier
|
||||
) {
|
||||
if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
PortraitKeyboardLoading(modifier)
|
||||
} else {
|
||||
LandscapeKeyboardLoading(modifier)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PortraitKeyboardLoading(
|
||||
modifier: Modifier
|
||||
) {
|
||||
ColumnWithConstraints(
|
||||
modifier = modifier
|
||||
) { constraints ->
|
||||
|
||||
val additionalButtonHeight by remember {
|
||||
mutableStateOf(constraints.maxHeight * 0.09f)
|
||||
}
|
||||
|
||||
val spacerHeight by remember {
|
||||
mutableStateOf(constraints.maxHeight * 0.025f)
|
||||
}
|
||||
|
||||
val additionalRowSpacedBy by remember {
|
||||
mutableStateOf(constraints.maxWidth * 0.03f)
|
||||
}
|
||||
|
||||
val weightModifier = Modifier.weight(1f)
|
||||
val additionalButtonModifier = Modifier
|
||||
.weight(1f)
|
||||
.height(additionalButtonHeight)
|
||||
|
||||
Spacer(modifier = Modifier.height(spacerHeight))
|
||||
|
||||
Row(
|
||||
modifier = Modifier,
|
||||
horizontalArrangement = Arrangement.spacedBy(additionalRowSpacedBy)
|
||||
) {
|
||||
// Additional buttons
|
||||
Box(weightModifier) {
|
||||
AdditionalButtonsPortrait(
|
||||
modifier = additionalButtonModifier,
|
||||
allowVibration = false,
|
||||
addSymbol = {},
|
||||
showAdditional = false,
|
||||
radianMode = false,
|
||||
toggleAngleMode = {},
|
||||
toggleInvMode = {}
|
||||
)
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier.size(additionalButtonHeight),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
// Expand/Collapse
|
||||
IconButton(
|
||||
onClick = { },
|
||||
colors = IconButtonDefaults.iconButtonColors(containerColor = MaterialTheme.colorScheme.inverseOnSurface)
|
||||
) {
|
||||
Icon(Icons.Default.ExpandLess, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(spacerHeight))
|
||||
|
||||
Box(
|
||||
modifier = weightModifier
|
||||
.clip(RoundedCornerShape(32.dp))
|
||||
.background(MaterialTheme.colorScheme.inverseOnSurface)
|
||||
.fillMaxSize()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(spacerHeight))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LandscapeKeyboardLoading(
|
||||
modifier: Modifier
|
||||
) {
|
||||
RowWithConstraints(modifier) { constraints ->
|
||||
val buttonModifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f)
|
||||
.padding(constraints.maxWidth * 0.005f, constraints.maxHeight * 0.02f)
|
||||
|
||||
AdditionalButtonsLandscape(
|
||||
modifier = Modifier.weight(1f),
|
||||
buttonModifier = buttonModifier,
|
||||
allowVibration = false,
|
||||
radianMode = false,
|
||||
addSymbol = {},
|
||||
toggleAngleMode = {},
|
||||
toggleInvMode = {}
|
||||
)
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(32.dp))
|
||||
.background(MaterialTheme.colorScheme.inverseOnSurface)
|
||||
.weight(5f)
|
||||
.fillMaxSize()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PortraitKeyboard(
|
||||
modifier: Modifier,
|
||||
|
@ -28,12 +28,15 @@ import androidx.compose.animation.expandHorizontally
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
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.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.SwapHoriz
|
||||
import androidx.compose.material3.Icon
|
||||
@ -48,6 +51,7 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@ -56,6 +60,7 @@ import androidx.compose.ui.text.TextRange
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.sadellie.unitto.core.base.OutputFormat
|
||||
@ -72,7 +77,6 @@ import com.sadellie.unitto.core.ui.common.textfield.UnformattedTextField
|
||||
import com.sadellie.unitto.data.common.format
|
||||
import com.sadellie.unitto.data.model.unit.AbstractUnit
|
||||
import com.sadellie.unitto.feature.converter.components.DefaultKeyboard
|
||||
import com.sadellie.unitto.feature.converter.components.LoadingKeyboard
|
||||
import com.sadellie.unitto.feature.converter.components.NumberBaseKeyboard
|
||||
import com.sadellie.unitto.feature.converter.components.UnitSelectionButton
|
||||
|
||||
@ -191,7 +195,12 @@ private fun ConverterLoading(modifier: Modifier) {
|
||||
}
|
||||
},
|
||||
content2 = {
|
||||
LoadingKeyboard(modifier = it)
|
||||
Box(
|
||||
modifier = it
|
||||
.clip(RoundedCornerShape(32.dp))
|
||||
.background(MaterialTheme.colorScheme.inverseOnSurface)
|
||||
.fillMaxSize()
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -18,19 +18,13 @@
|
||||
|
||||
package com.sadellie.unitto.feature.converter.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.sadellie.unitto.core.base.Token
|
||||
import com.sadellie.unitto.core.ui.common.ColumnWithConstraints
|
||||
import com.sadellie.unitto.core.ui.common.KeyboardButtonFilled
|
||||
@ -169,15 +163,3 @@ internal fun NumberBaseKeyboard(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun LoadingKeyboard(
|
||||
modifier: Modifier,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.clip(RoundedCornerShape(32.dp))
|
||||
.background(MaterialTheme.colorScheme.inverseOnSurface)
|
||||
.fillMaxSize()
|
||||
)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user